이 포스트는 안드로이드 공식 홈페이지 Codelab 을 기반으로 작성되었습니다.
Navigation 활용법을 익히기 위해 안드로이드 공식 Codelab을 따라 연습해보기로 했다.
아래와 같은 앱을 따라서 만들어 볼 예정이다.
아래 Github 링크를 복사해서 프로젝트를 클론한다.
git clone https://github.com/googlecodelabs/android-navigation
탐색 그래프(NavGraph)는 사용자가 앱에서 선택할 수 있는 가능한 모든 경로를 정의하는 리소스 유형이다. 지정된 대상에서 도달할 수 있는 모든 대상을 시각적으로 표시한다. Android 스튜디오에서는 Navigation Editor로 그래프를 표시한다.
res/navigation/mobile_navigation.xml
을 연다.그러면 아래 이미지와 같은 화면이 표시된다.
탐색 그래프에서 대상 사이의 화살표를 작업이라고 부른다.
대상을 클릭하여 속성을 확인한다.
화살표로 효시된 작업을 클릭하여 속성을 확인한다.
Navigation Editor에서 Code 탭을 클릭한다. 그러면 아래와 같이 XML이 표시된다.
<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"
app:startDestination="@+id/home_dest">
<!-- ...tags for fragments and activities here -->
</navigation>
<navigation>
은 모든 탐색 그래프의 루트 노드이다.<navigation>
에는 <activity>
또는 <fragment>
요소로 표시된 대상이 하나 이상 포함된다.app:startDestination
은 사용자가 앱을 처음 열 때 기본적으로 실행되는 대상을 지정하는 속성입니다.프래그먼트 대상 코드는 아래와 같다.
<fragment
android:id="@+id/flow_step_one_dest"
android:name="com.example.android.codelabs.navigation.FlowStepFragment"
tools:layout="@layout/flow_step_one_fragment">
<argument
.../>
<action
android:id="@+id/next_action"
app:destination="@+id/flow_step_two_dest">
</action>
</fragment>
res/navigation/mobile_navigation.xml
을 열고 Design 탭을 클릭.XML 파일을 직접 수정하여 대상을 추가할 수도 있다.
mobile_navigation.xml
<fragment
android:id="@+id/settings_dest"
android:name="com.example.android.codelabs.navigation.SettingsFragment"
android:label="@string/settings"
tools:layout="@layout/settings_fragment" />
Navigation에서는 Activity를 앱의 시작 지점으로 사용할 것을 권장한다.
프래그먼트는 실제 대상(Destination)별 레이아웃이 된다.
모든 대상이 잘 나타나도록 하려면 Activity 레이아웃을 수정해 NavHostFragment
라는 특수 위젯을 포함해야한다. NavHostFragment
는 탐색 그래프를 탐색할 때 여러 프래그먼트 대상을 안팎으로 교체한다.
사용자가 버튼을 클릭하는 등 작업을 할 때 Navigation 명령어를 트리거해야 한다. NavController
라는 특수 클래스가 NavHostFragment
에서 프래그먼트 교체를 트리거한다.
// Command to navigate to flow_step_one_dest
findNavController().navigate(R.id.flow_step_one_dest)
NavController
가 navigate()
또는 popBackStack()
과 같은 메서드를 호출할 때 이동하는 대상의 유형에 따라 이러한 명령어를 적절한 프레임워크 작업으로 변환한다. 예를 들어 Activity 대상과 함께 navigate()
를 호출하면 NavController
에서 개발자를 대신해 startActivity()
를 호출한다.
NavHostFragment
와 연결된 NavController
객체를 가져오는 방법은 여러개가 있다. Kotlin에서는 탐색 명령어를 프래그먼트 내에서 호출하는지 활동에서 호출하는지 뷰에서 호출하는지에 따라 다음 확장 함수 중 하나를 사용하는 것이 좋다.
Fragment.findNavController()
View.findNavController()
Activity.findNavController(viewId: Int)
NavController
를 사용하여 다른 대상으로 이동할 수 있다. Navigate To Destination 버튼을 연결하여 flow_step_one_dest
대상(FlowStepFragment
인 대상)으로 이동한다.
HomeFragment.kt
val button = view.findViewById<Button>(R.id.navigate_destination_button)
button?.setOnClickListener {
findNavController().navigate(R.id.flow_step_one_dest, null)
}
현재 navigate()
호출로 인한 화면 전환에는 아래처럼 아무 애니메이션 효과도 적용되어 있지 않다.
기본 전환은 NavOptions
를 포함해 재정의할 수 있다.
애니메이션의 경우 anim
리소스 폴더에서 XML 애니메이션 리소스를 정의하고 사용할 수 있다.
Navigate To Destination 버튼을 누르면 전환 애니메이션이 표시되도록 코드를 변경한다.
HomeFragment.kt
val options = navOptions {
anim {
enter = R.anim.slide_in_right
exit = R.anim.slide_out_left
popEnter = R.anim.slide_in_left
popExit = R.anim.slide_out_right
}
}
view.findViewById<Button>(R.id.navigate_destination_button)?.setOnClickListener {
findNavController().navigate(R.id.flow_step_one_dest, null, options)
}
화면 전환 코드를 위 코드로 변경하면 HomeFragment에서 전환될 때 애니메이션 효과가 적용되는 것을 확인할 수 있다.
다음 포스트에 계속...