Navigation Component(1)
Android Jetpack의 Navigation Componet는 단순한 버튼 클릭부터 좀 더 복잡한 패턴(앱바, 탐색 창)에 이르기까지 여러 가지 탐색을 구현하도록 도와준다.
1. Navigation Component 장점
- fragment transactions 자동 처리
- 올바른 up, back 처리
- animations 및 transactions에 표준화된 리소스 제공
- 딥 링크 구현 및 처리
- 추가 작업 없이 탐색 UI 패턴(예: 탐색창, 하단 탐색 메뉴) 구현
- Safe Args
- Android Studio에서 앱의 탐색 흐름을 시각화하고 수정 가능
2. Navigation 구성요소
- Navigation graph
사용자가 앱에서 선택할 수 있는 가능한 모든 경로를 정의하는 XML Resource이다.
지정된 대상에서 도달할 수 있는 모든 대상을 시각적으로 표시한다.
Android Studio에서는 Navigation Editor에 그래프를 표시한다.
- NavHostFragment(Layout XML View)
Navigation graph에서 대상을 표시하는 빈 컨테이너
- NavController
Navigation graph내에서 현재 위치를 계속 추적하는 객체.
탐색 시 이동하려는 위치나 Navigation Graph에서 선택할려는 경로를 알려주면 NavHostFragment에 적절한 대상(Destinations)을 표시한다.
3. 환경 설정
build.gradle 파일에 다음 dependencies를 추가
dependencies {
def nav_version = "2.3.5"
// Java language implementation
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"
// Kotlin
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
// Feature module Support
implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
// Testing Navigation
androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
// Jetpack Compose Integration
implementation "androidx.navigation:navigation-compose:1.0.0-alpha10"
}
4. 탐색 그래프(Navigation graph) 만들기
Project창에서 res 디렉토리를 마우스 오른쪽 버튼으로 클릭하고 New > Android Resource File을 선택한다.
File name 필드에 resource file 이름을 입력, Resource type 드롭다운 목록에서 Navigation을 선택한다.
Navigation Editor의 Code탭을 클릭하면 아래와 비슷한 XML을 확인할 수 있다
<?xml version="1.0" encoding="utf-8"?>
<navigation
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph">
</navigation>
5. NavHostFragment 추가
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="ndroidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"/>
</androidx.constraintlayout.widget.ConstraintLayout>
android:name 속성은 NavHost 구현 클래스 이름
app:NavGraph 속성은 NavHostFragment를 탐색 그래프와 연결한다.
app:defaultNavHost = "true" 속성을 사용하면 NavHostFragment가 시스템 백버튼을 가로챈다. 동일한 레이아웃에 여러 Host가 있어도 한 NavHost만 기본으로 지정할 수 있다.
6. 탐색 그래프에 대상(Destinations) 추가
기존 Fragment, Activity를 이용해서 또는 Navigation Editor를 사용하여 새로운 대상(Destinations)을 만들거나 교체할 수 있다.
<?xml version="1.0" encoding="utf-8"?>
<navigation
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/home_dest">
<fragment
android:id="@+id/home_dest"
android:name="test.com.navigation.HomeFragment"
android:label="Home"
tools:layout="@layout/home_fragment">
</fragment>
<fragment
android:id="@+id/flow_step_one_dest"
android:name="test.com.navigation.FlowStepFragment"
android:label="Step_1"
tools:layout="@layout/flow_step_one_fragment">
<argument
android:name="flowStepNumber"
android:defaultValue="1"
app:argType="integer" />
<action
android:id="@+id/next_action"
app:destination="@id/flow_step_two_dest" />
</fragment>
<fragment
android:id="@+id/flow_step_two_dest"
android:name="test.com.navigation.FlowStepFragment"
android:label="Step_2"
tools:layout="@layout/flow_step_two_fragment">
<argument
android:name="flowStepNumber"
android:defaultValue="2"
app:argType="integer" />
<action
android:id="@+id/next_action"
app:destination="@id/home_dest" />
</fragment>
</navigation>
app:startDestination 속성은 시작 대상(Destinations) 설정
android:name 속성은 대상(Destinations) 구현 클래스 이름
- argument
대상(Destinations)간의 인수값 정의
인수 이름, 인수 유형, 인수의 null 허용 여부 및 필요하다면 default값을 입력하여 정의한다.
코드에선 getArguments() 메서드를 사용하여 Bundle을 검색하여 데이터 사용
val flowStepNumber = arguments?.getInt("flowStepNumber")
Log.d(TAG, "flowStepNumber = $flowStepNumber")
자세한 내용은 https://developer.android.com/guide/navigation/navigation-pass-data 페이지 참조