이 포스트는 안드로이드 공식 홈페이지 Codelab 을 기반으로 작성되었습니다.
Navigation 구성요소에는 NavigationUI
클래스와 navigation-ui-ktx
kotlin 확장 프로그램이 포함되어 있다. NavigationUI
에는 메뉴 항목을 탐색 대상과 연결하는 정적 메서드가 있고 navigation-ui-ktx
는 동일한 작업을 실행하는 확장 함수 모음이다. NavigationUI
가 현재 그래프에서 대상과 ID가 동일한 메뉴 항목을 찾으면 그 대상으로 이동하도록 메뉴 항목을 구성한다.
onCreateOptionsMenu
에서 overflow_menu
메뉴를 확장하는 코드가 어떤지 확인한다.res/menu/overflow_menu.xml
을 연다.settings_dest
를 포함하도록 더보기 메뉴를 업데이트한다.overflow_menu.xml
<item
android:id="@+id/settings_dest"
android:icon="@drawable/ic_settings"
android:menuCategory="secondary"
android:title="@string/settings" />
MainActivity.kt
의 onOptionsItemSelected
메서드에서 NavigationUI가 onNavDestinationSelected
메서드를 처리하도록 한다. override fun onOptionsItemSelected(item: MenuItem): Boolean {
return item.onNavDestinationSelected(findNavController(R.id.my_nav_host_fragment))
|| super.onOptionsItemSelected(item)
}
overflow_menu.xml
의 메뉴 버튼 id값이 settings_dest
이므로 해당 id값과 동일한 destination이 있을 경우 해당 대상으로 탐색이 진행된다.
코드에 이미 BottomNavigationView가 XML상에서 구성되어 있지만 버튼을 눌러도 이동하지 않는다.
res/layout/navigation_activity/navigation_activity.xml (h470dp)
를 열고 Text 탭을 클릭한다.<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_nav_menu" />
BottomNavigationView의 menu 속성으로 bottom_nav_menu.xml
이 적용되어 있는 것을 확인할 수 있다.
res/menu/bottom_nav_menu.xml
을 연다.<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@id/home_dest"
android:icon="@drawable/ic_home"
android:title="@string/home" />
<item
android:id="@id/deeplink_dest"
android:icon="@drawable/ic_android"
android:title="@string/deeplink" />
</menu>
각 메뉴 항목의 ID값이 탐색 대상(Destination)의 ID값과 일치하는 것을 확인할 수 있다.
MainActivity.kt
를 연다.
setupWithNavController(bottomNavigationView: BottomNavigationView, navController: NavController)
를 사용하여 setupBottomNavMenu
메서드를 구현한다.
MainActivity.kt
private fun setupBottomNavMenu(navController: NavController) {
val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav_view)
bottomNav?.setupWithNavController(navController)
}
이제 하단 탐색 메뉴가 작동한다.
태블릿 등의 큰 화면에서 DrawerLayout
형식을 사용하는 탐색 창은 어떻게 구현하는지 살펴보자.
navigation_activity.xml
과 navigation_activity.xml (w960dp)
을 모두 연다.태블릿 버전(w960dp)에선 NavigationView는 항상 화면에 표시되고 더 작은 기기에서는 NavigationView가 DrawerLayout 내에 중첩되어 있는 것을 확인할 수 있다.
MainActivity.kt
를 연다.setupWithNavController(navigationView: NavigationView, navController: NavController)
를 사용하여 setupNavigationMenu
메서드를 구현한다. 이 버전의 메서드가 BottomNavigationView
가 아닌 NavigationView
를 사용하는 방식을 확인한다.MainActivity.kt
private fun setupNavigationMenu(navController: NavController) {
val sideNavView = findViewById<NavigationView>(R.id.nav_view)
sideNavView?.setupWithNavController(navController)
}
이제 NavigationMenu가 화면에 표시되지만 ActionBar에는 아이콘이 표시되지 않는다. (태블릿에서는 보이지만 폴드 수준의 크기에서는 보이지 않음.)
ActionBar
를 설정하려면 AppBarConfiguration
의 인스턴스를 만들어야한다.
AppBarConfiguration
을 만든다.MainActivity.kt
val drawerLayout : DrawerLayout? = findViewById(R.id.drawer_layout)
appBarConfiguration = AppBarConfiguration(
setOf(R.id.home_dest, R.id.deeplink_dest),
drawerLayout)
이제 AppBarConfiguration
이 있으므로 NavigationUI.setupActionBarWithNavController
를 호출할 수 있다. 그러면 아래 작업이 실행된다.
1. 대상의 라벨에 따라 ActionBar에 제목 표시
2. 최상위 대상에 없을 때마다 위로 버튼 표시
3. 최상위 대상에 있을 때 창 아이콘(햄버거 아이콘) 표시
setupActionBarWithNavController
를 구현한다.MainActivity.kt
private fun setupActionBar(navController: NavController,
appBarConfig : AppBarConfiguration) {
setupActionBarWithNavController(navController, appBarConfig)
}
AppBarConfiguration
을 사용하여 onSupportNavigationUp
을 재정의하고 NavigationUi.navigateUp
을 호출한다.MainActivity.kt
override fun onSupportNavigateUp(): Boolean {
return findNavController(R.id.my_nav_host_fragment).navigateUp(appBarConfiguration)
}
새 대상을 NavigationView
에 추가하는 것은 간단하다. 탐색 창이 함께 작동하도록 한 후 새 메뉴 항목을 추가해주면 된다.
menu/nav_drawer_menu.xml
을 연다.settings_dest
의 새 메뉴 항목을 추가한다.nav_drawer_menu.xml
<item
android:id="@+id/settings_dest"
android:icon="@drawable/ic_settings"
android:title="@string/settings" />
이제 탐색 창에 설정 Destination이 표시된다.