Phần 3: Android Bottom Navigation - Back Stacks

Vấn đề gặp phải như preview ở Phần 2:

  • Với trường hợp 1 tab chỉ có 1 fragment thì không vấn đề gì. Nhưng trong 1 tab có thêm các fragment con thì khi ta điều hướng qua 1 fragment mới thì nó sẽ replace fragment cũ, nghĩa là trạng thái fragment cũ không được lưu.

Issue: Fragment bị khởi tạo lại. Issue dự định resolve ở version 2.4.0 nhưng version mới nhất hiện tại mới là 2.3.0 và điều đó buộc chúng ta phải bỏ thằng navigation, thay thế bằng thư viện bottomnavigator của pandora

Bạn có thể thêm các ô EditText nhập dữ liệu, sau đó điều hướng qua lại giữa các fragment để thấy kết quả nhé, trạng thái của Fragment đã được lưu.

bottom_nav_preview_3

Các bước setup project như sau#

Dependency#

1
implementation 'com.pandora.bottomnavigator:bottom-navigator:1.2'

Layout Activity#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="0dp"
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" />

<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="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />

MainActivity#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private lateinit var navigator: BottomNavigator

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

navigator = BottomNavigator.onCreate(
fragmentContainer = R.id.fragment_container,
bottomNavigationView = findViewById(R.id.nav_view),
rootFragmentsFactory = mapOf(
R.id.navigation_monster to { MonsterFragment() },
R.id.navigation_slug to { SlugFragment() }
),
defaultTab = R.id.navigation_monster,
activity = this
)
}

override fun onBackPressed() {
if (!navigator.pop()) {
super.onBackPressed()
}
}

Code điều hướng#

Từ MonsterFragment

1
2
3
4
navigateToMonkey?.setOnClickListener {
val navigator = BottomNavigator.provide(activity!!)
navigator.addFragment(MonkeyFragment())
}

Từ SlugFragment

1
2
3
4
navigateToSlash?.setOnClickListener {
val navigator = BottomNavigator.provide(activity!!)
navigator.addFragment(SlashFragment())
}

Như vậy, Project của chúng ta sẽ sử dụng BottomNavigationView làm menu tab, BottomNavigator làm Fragment Container để điều hướng và giữ trạng thái.


Source code có thể tải về tại Github