我正在使用 Android 导航组件(当前为 v2.1.0),并且我正在尝试找出如何最好地处理需要自己的 BottomNavigationView 的子屏幕,而 MainActivity 已经具有顶级的 BottomNavigationView。
在大多数情况下,谷歌似乎真的提倡单一活动架构。这是我目前拥有它的方式:
- Main Activity
- NavHostFragment & Top Level BottomNav
NavHost has navGraph of main_navigation.xml: this has the MainActivity top level
bottom navigation fragments, (e.g. Groups, Courses, Profile etc.) and also a link to the child
fragment which should have its own BottomNav
- ChildFragment
- Has its own NavHostFragment in its layout, and its own BottomNav
This NavHost has navGraph of childfragment_navigation.xml: which, similar to MainActivity,
handles the bottom navigation fragments for the child fragment etc. etc.
这带来了一些问题。首先,如果用户导航到这个子片段,我必须显示和隐藏 MainActivity BottomNavigationView,如下所示:
private fun setupNavController() {
val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_groups, R.id.navigation_courses, R.id.navigation_profile
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
nav_view.setupWithNavController(navController)
navController.addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.navigation_groups, R.id.navigation_courses, R.id.navigation_profile -> showBottomNavigation()
else -> hideBottomNavigation()
}
}
}
override fun onSupportNavigateUp(): Boolean {
return findNavController(R.id.nav_host_fragment).navigateUp() || super.onSupportNavigateUp()
}
private fun hideBottomNavigation() {
nav_view.visibility = View.GONE
}
private fun showBottomNavigation() {
nav_view.visibility = View.VISIBLE
}
这感觉真的很笨重,而且有点 hack,并且还开始在 MainActivity 中添加一些不需要的视图逻辑。
第二个问题与 appbar 和 backstack 的东西有关。一旦我在子片段中,我会获得该子片段的更新工具栏标题,但是任何进一步的操作栏更新最初都不起作用,如果我深入到更多的子片段,按回最初将不起作用除了带我回到 MainActivity。添加app:defaultNavHost="true"
到两个 NavHostFragments 似乎解决了一些问题,即后退按钮在子片段中正常工作一次,虽然应用栏向上按钮不适用于子片段的子片段,但它总是回到 MainActivity。
我试着把它放在子片段中:
NavigationUI.setupActionBarWithNavController(activity as AppCompatActivity, navController)
这会更新工具栏标题,但向上按钮仍会返回到 Main Activity。
对于这种应用程序结构,我可以想到 3 种可能的解决方案(子片段有自己的底部导航):
- 放弃 Single Activity 架构,让 Child Fragment 成为自己的 Activity
- 只需使用一个 nav_graph、一个 NavHostFragment 和一个 BottomNav,然后想办法在孩子身上换掉 BottomNavigation 菜单 - 任何有关这方面的指导都将不胜感激
- 坚持让这个子片段拥有自己的 NavHostFragment 和 BottomNav,并找出一种方法来处理后退堆栈、应用栏和底部导航的显示/隐藏