我已经看到了处理
Navigation
的自定义后退导航的常用代码,这基本上就是 文档所得到的,但我认为这对于我的用例来说还不够。文档中的后退按钮侦听器确实可以工作,但工具栏后退按钮在我的情况下不会触发后退按钮侦听器,或者由于我的用例而无法正常工作。我的导航是这样设置的:
Login ---> MainModule1 ---> MainModule2 ---> SubModule2 to 3
| | |
|->SignUpModule |->SubModule1 |-> SubModule 4
如果我转到 SubModule1 并按工具栏后退按钮返回到 MainModule1,我注意到传递给
requireActivity().onBackPressedDispatcher.addCallback(this)
的回调没有被调用。如果我按下“物理”后退按钮,它就会被触发。
到目前为止,我的代码如下:
下面的代码在 MainActivity 的 onCreate 中被调用
private fun setupNav() {
setSupportActionBar(binding.appContentMain.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_monitoring_fragment, R.id.nav_dashboard_fragment, R.id.nav_logout, R.id.nav_login_fragment
), binding.drawerLayout
)
navController = findNavController(R.id.nav_host_fragment_content_main)
setupActionBarWithNavController(navController, appBarConfiguration)
binding.navView.setupWithNavController(navController)
binding.navView.setNavigationItemSelectedListener(this)
}
然后这是
Fragment
的代码,希望能够同时监听“物理”和工具栏后按。
override fun onAttach(context: Context) {
super.onAttach(context)
val onBackPressedCallback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
//I want to pass back a variable from the current Fragment to MainModule1
val action = AccountProfileFragmentDirections.goBackToDashboardFromAccountProfile(currentAccount)
findNavController().navigate(action)
}
}
requireActivity().onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
}
如果我在 MainActivity 中添加一个
onOptionsItemSelected
,如下所示:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
return true
}
return true
}
在 MainActivity 中,SubModule1 上工具栏的后退按钮确实会触发
onBackPressedDispatcher
回调。但是,如果您在“汉堡模式”下再次单击它,不幸的是,SubModule1 会再次显示。如果我重新启动应用程序并单击汉堡菜单,MainModule1 就会闪烁,我认为这意味着它会重新显示
我想我已经找到了解决这个问题的方法,而且非常简单。
首先,我们希望将传递给
AppBarConfiguration
的导航 ID 集放置到一个变量中,因为我们需要它来完成 onOptionsItemSelected
中的某些操作。你需要这样的东西:
private val navBaseNodeSet = setOf(
R.id.nav_monitoring_fragment, R.id.nav_dashboard_fragment, R.id.nav_logout, R.id.nav_login_fragment
)
当然你需要再次将其传递给
AppBarConfiguration
。
appBarConfiguration = AppBarConfiguration(navBaseNodeSet, binding.drawerLayout)
这是重要的一点,这就是
onOptionsItemSelected
应该是什么样子:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
return if( !navBaseNodeSet.contains(navController.currentDestination?.id) ){
onBackPressed()
true
}else{
false
}
}
return false
}