SW 공부노트
[안드로이드] Toolbar Custom with Navigation Components 본문
https://developer.android.com/guide/navigation/navigation-ui?hl=ko
NavigationUI로 UI 구성요소 업데이트 | Android 개발자 | Android Developers
NavigationUI로 UI 구성요소 업데이트 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 탐색 구성요소에는 NavigationUI 클래스가 포함되어 있습니다. 이 클래스에는
developer.android.com
Android Jetpack의 Navigation 기능을 적용한 커스텀 툴바를 구현하였다.
NavigationUI는 Toolbar, CollapsingToolbarLayout, Actionbar와 같은 상단 앱 바 유형을 지원한다.
이번 포스팅에서는 Toolbar를 사용할 예정이다.
0. 기본 설정
- navigation 파일 (ex. nav_graph)
- theme에서 NoActionBar 설정
1. 툴바 레이아웃 파일 생성
navigationIcon 속성은 기본 Toolbar에선 사용할 수 있지만 Navigation Components와 함께 사용하면 적용되지 않는다.
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.appcompat.widget.Toolbar
android:id="@+id/main_tool_bar"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize"
android:background="@color/white"/>
<!--app:navigationIcon="@drawable/baseline_arrow"-->
</layout>
2. activity_main.xml 파일에 툴바 추가
<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">
<include
android:id="@+id/main_toolbar"
layout="@layout/toolbar"/>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?actionBarSize"
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"/>
</androidx.constraintlayout.widget.ConstraintLayout>
3. Activity 파일에서 툴바 관련 설정
- setUpWithNavController() 호출 -> 커스텀 툴바에서 Navigation 기능 사용하기 위한 설정
- AppBarConfiguration 객체에 탐색 그래프 전달
- BottomNavigation과 같이 최상위 수준의 화면이 여러개이면 인수로 대상 ID 집합 전달
-> Up 버튼 기능만 구현하는 이번 포스팅에선 사용되지 않지만 메뉴 등 추가적인 기능 구현 시 사용될 수 있음
- addOnDestinationChangedListener() -> 화면이 바뀔때마다 호출되는 메서드
툴바 레이아웃에 navigationIcon을 설정해둬도 Navigation Components에서 제공하는 디폴트 아이콘(<-)이 뜨는 문제가 있었다. 찾아보니 현재까지는 해당 아이콘을 커스텀할 수 있는 방법이 없다고 한다 😢
따라서 addOnDestinationChangedListener 메서드를 통해 따로 아이콘을 설정해주었다.
자세한 내용은 아래 글을 참고하길 바란다.
class MainActivity : BaseActivity<ActivityMainBinding>(R.layout.activity_main) {
private lateinit var navController: NavController
private lateinit var appBarConfiguration: AppBarConfiguration
// onCreate() 내부에서 호출
override fun init() {
val navHost = supportFragmentManager.findFragmentById(R.id.nav_host) as NavHost
val toolbar = findViewById<Toolbar>(R.id.main_toolbar)
navController = navHost.navController
appBarConfiguration = AppBarConfiguration(navController.graph)
toolbar.setupWithNavController(navController, appBarConfiguration)
navController.addOnDestinationChangedListener { controller, destination, arguments ->
if (destination.parent!!.startDestinationId != destination.id)
toolbar.setNavigationIcon(R.drawable.baseline_arrow)
}
}
}
만약 toolbar를 통해 레이아웃 커스텀만 하고, 기존 Action Bar 기능은 그대로 사용하고 싶다면 setSupportActionBar를 통해 툴바 레이아웃 적용 후 Action Bar에서 Navigation Component 기능을 사용할 수 있도록 설정해주면 된다.
toolbar를 적용한 위 케이스와 달리 Action Bar를 적용하므로 setupActionBarWithNavContoller 메서드를 사용한다.
// onCreate() 내부에서 호출
override fun init() {
val navHost = supportFragmentManager.findFragmentById(R.id.nav_host) as NavHost
val toolbar = findViewById<Toolbar>(R.id.main_toolbar)
navController = navHost.navController
setSupportActionBar(toolbar)
supportActionBar!!.setDisplayShowTitleEnabled(false) // 타이틀명 안보이게 지정
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
navController.addOnDestinationChangedListener { controller, destination, arguments ->
if (destination.parent!!.startDestinationId != destination.id)
toolbar.setNavigationIcon(R.drawable.baseline_arrow)
}
}
// Up 버튼 기능
override fun onSupportNavigateUp(): Boolean {
return super.onSupportNavigateUp() || navController.navigateUp(appBarConfiguration)
}
- setSupportActionBar()에 Toolbar를 인수로 전달하면 Actionbar가 그 Toolbar의 완전한 소유권을 갖게 되므로 이 함수를 호출한 후에는 Toolbar API를 사용하면 안된다. -> ActionBar Support를 사용해 ActionBar를 NavController에 연결할 수 있다.
- AppBarConfiguration 객체는 상단 바 관련 구성 옵션을 처리하는 객체
- Toolbar를 사용할 때는 Navigation에서 탐색 버튼의 클릭 이벤트를 자동으로 처리하므로 onSupportNavigateUp() 재정의 X
- Toolbar + AppLayout을 통해 탭이 있는 상단 바 설정 가능
- Activity에서 호스팅하는 단일 상단 바 대신 프래그먼트마다 다른 상단 바를 사용하려면 프래그먼트의 onViewCreated() 메서드 내에서 setupWithNavController를 호출해야 한다.
Reference)
https://chachas.tistory.com/17
[ Android ] Navigation
목차 시중에 나와있는 앱을 보면 복잡하게 이루어진 경우가 대부분으로 하나의 화면이나 두 개의 버튼으로 이루어진 화면처럼 간단하게 이루어진 앱을 찾아보기는 힘듭니다. Navigation은 화면을
chachas.tistory.com