일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Fragment에서 Activity의 함수 사용하기
- high order function
- espresso
- searchview
- 리사이클러뷰
- IntentTestRule
- 안드로이드
- viewholder
- recyclerview
- 구분선
- 안드로이드13
- 테마 아이콘
- 안드로이드개발레벨업교과서
- 안드로이드스튜디오
- 고차함수
- ui test
- Fragment 수동 추가
- 코틀린
- 코딜리티
- adapter
- fragment
- 뷰변경 감지
- LayoutManger
- Android
- Error:Execution failed for task ':app:mergeDebugResources'
- binding adapter
- 스와이프
- 생명주기
- ActivityTestRule
- 재사용
Archives
- Today
- Total
룬아님의 취중코딩
Android Navigation Component save state on Bottom Navigation 본문
Bottom Navigation과 Navigation Component를 같이 사용했을 때 네비게이션 버튼을 누를 때마다 onCreate가 불린다.
이유는 Navigation Component에서 화면이 변경 될 때에 show, hide 로직이 아닌 replace를 사용하기 때문인데
지금은 override도 불가능하고 기본적으로 지원하지도 않기 때문에 추후 업데이트를 지켜봐야 한다.
하지만 구글에서 제공한 Android Architecture Components Advanced Navigation Sample에서 navigation graph를 분할하여 상태를 저장할 수 있도록 하는 예제를 공개하였다.
하지만 이 역시 네비게이션 버튼에 의한 프래그먼트 이동에 한에서만 상태를 저장하지 navigation component를 이용하여 이동하고 백스탭으로 돌아오는 것은 아직도 onCreate를 호출한다.
위의 예제를 사용하기 위해서는
1. build.gradle
implementation 'androidx.navigation:navigation-fragment:2.0.0'
implementation 'androidx.navigation:navigation-ui:2.0.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.0.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation "androidx.fragment:fragment:1.2.0-rc02"
2. 메뉴에서 설정한 바텀 네비게이션 아이템의 id와 navigation의 id가 일치하여야 작동한다.
<!-- bottom_nav_menu.xml !-->
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/notices"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_notice" />
<item
android:id="@+id/setting"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_setting" />
</menu>
<!-- notices.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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/notices"
app:startDestination="@+id/navigation_notice">
<fragment
android:id="@+id/navigation_notice"
android:name="com.mashup.app.notices.NoticesFragment"
android:label="@string/title_notice"
tools:layout="@layout/notices_fragment" />
</navigation>
3. activity_main.xml
<?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"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="@color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_container"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/bottom_line"
android:layout_width="match_parent"
android:layout_height="4dp"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="@drawable/shadow_bottom_to_up" />
</androidx.constraintlayout.widget.ConstraintLayout>
4. MainActivity.kt
class MainActivity : AppCompatActivity() {
private var currentNavController: LiveData<NavController>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
setupBottomNavigationBar()
} // Else, need to wait for onRestoreInstanceState
}
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
super.onRestoreInstanceState(savedInstanceState)
// Now that BottomNavigationBar has restored its instance state
// and its selectedItemId, we can proceed with setting up the
// BottomNavigationBar with Navigation
setupBottomNavigationBar()
}
/**
* Called on first creation and when restoring state.
*/
private fun setupBottomNavigationBar() {
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.nav_view) //BottomNavigationView의 id
val navGraphIds = listOf(R.navigation.notices, R.navigation.setting)//graph들의 id
// Setup the bottom navigation view with a list of navigation graphs
val controller = bottomNavigationView.setupWithNavController(
navGraphIds = navGraphIds,
fragmentManager = supportFragmentManager,
containerId = R.id.nav_host_container, //FragmentContainerView의 id
intent = intent
)
// Whenever the selected controller changes, setup the action bar.
/*controller.observe(this, Observer { navController ->
setupActionBarWithNavController(navController)
})*/
//액션바 관련 코드 (액션바를 사용하지 않기 때문에 주석처리)
currentNavController = controller
}
override fun onSupportNavigateUp(): Boolean {
return currentNavController?.value?.navigateUp() ?: false
}
}
5. NavigationExtensions
반응형
'개발 > 안드로이드 개발' 카테고리의 다른 글
Databinding으로 visibility 처리하기 (0) | 2019.12.18 |
---|---|
(Android) 투명 테마로 투명 화면 만들기 (0) | 2019.11.28 |
RxJava + Retrofit2 Error 객체로 받아 커스텀 하기 (0) | 2019.11.25 |
Recyclerview + GridLayout + databinding + Multi Item ViewType (0) | 2019.11.22 |
(koin) inject 할때에 parameter 전달하기 (1) | 2019.11.21 |
Comments