有一種場景慕购,NavigationRailView + fragment + Navigation ,通過 findNavController().navigate() 跳轉至DetailFragment僻肖,點擊NavigationRailView 其他標簽嫌拣,再點回上一次的標簽,此時標簽未被選中,顯示的頁面為之前操作跳轉的DetailFragment妒挎。必須在DetailFragment 中 調用 findNavController().popBackStack() 返回,標簽才會被選中西饵。如何在NavigationRailView 標簽點擊時酝掩,每次都顯示當前標簽下的首頁fragment?眷柔?期虾?
2022-12-15 更新
通過反復試驗 可以使用 findNavController().clearBackStack() 在切換新的fragment 里 將之前的fragment 清除
override fun onAttach(context: Context) {
super.onAttach(context)
findNavController().clearBackStack(R.id.VideoFragment)
}
原理待分析,暫且解決了我的問題吧驯嘱。镶苞。。
2023-04-23 再次更新鞠评,終極解決方案茂蚓;
借助ChatGpt的幫助:NavigationRailView 與 NavHost 組件進行導航,即 每個tab標簽對應一組NavHost剃幌。以兩個tab為例具體步驟:
1.創(chuàng)建多個 NavGraph
在項目中創(chuàng)建多個 NavGraph聋涨,每個 NavGraph 代表應用程序的不同區(qū)域或不同的功能模塊。我們可以使用 navigation 組件在 res 目錄下的 navigation 文件夾中創(chuàng)建每個 NavGraph负乡。
2.在 XML 布局文件中添加
NavigationRailView
在主 XML 布局文件中添加 NavigationRailView牍白,并將其與 NavHost 組件進行關聯(lián)。以下是一個示例 XML 布局文件:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.navigation.NavigationRailView
android:id="@+id/navigation_rail"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="0dp"
android:layout_marginRight="0dp"
android:background="#fff"
app:menu="@menu/navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="1.0"
app:itemIconPadding="12dp"
app:itemTextAppearance="@style/TextAppearance.AppCompat.Body2"
app:itemTextColor="@drawable/nav_item_color_state"
app:selectedItem="@id/home" />
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:navGraph="@navigation/home_nav"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@+id/navigation_rail"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
3.創(chuàng)建 menu 資源文件
我們需要在 res/menu 目錄下創(chuàng)建一個 menu 資源文件抖棘,并將其與 NavigationRailView 中的 app:menu 屬性關聯(lián)淹朋。在該文件中,我們可以添加菜單項钉答,這些菜單項將用于切換 NavHost 中的不同 NavGraph础芍。以下是一個示例 menu 文件:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/home"
android:icon="@drawable/ic_home"
android:title="Home" />
<item
android:id="@+id/settings"
android:icon="@drawable/ic_settings"
android:title="Settings" />
</group>
</menu>
此菜單將在 NavigationRailView 中顯示兩個菜單項,分別用于切換到 home_nav 和 settings_nav数尿。
4.在 Activity 或 Fragment 中實現(xiàn)
NavigationRailView.OnItemSelectedListener
我們需要在 Activity 或 Fragment 中實現(xiàn) NavigationRailView.OnItemSelectedListener 接口仑性。用戶單擊 NavigationRailView 中的菜單項時調用。在 onNavigationItemSelected 方法中右蹦,我們需要根據(jù)用戶單擊的菜單項 ID 加載相應的 NavGraph诊杆。核心代碼:
..........
override fun onNavigationItemSelected(item: MenuItem): Boolean {
val navController = nav_host_fragment.findNavController()
when (item.itemId) {
R.id.home -> {
navController.setGraph(R.navigation.home_nav)
return true
}
R.id.settings -> {
navController.setGraph(R.navigation.settings_nav)
return true
}
else -> return false
}
}
}
.......
在 onNavigationItemSelected 方法中,我們獲取當前 NavHost 中的 NavController 對象何陆,并根據(jù)用戶單擊的菜單項 ID 加載相應的 NavGraph晨汹。每一次切換相當于重新設置新的路由,這樣不管在那個標簽下進行跳轉贷盲,再切換標簽淘这,之前的fragment都會出棧剥扣。保證每一次切換都回到當前標簽下的首頁。