我需要显示自定义AlertDialog
,但前提是调用NavController.navigateUp()
后没有更多的片段。我当前的代码做了类似的事情,但它有一个错误:
override fun onBackPressed() {
if (navController.navigateUp()) {
return
}
showQuitDialog()
}
这有点用,但是如果我取消AlertDialog
并且不退出应用程序,navController
已经导航到NavGraph
根,这不是AlertDialog
出现时我所在的片段。因此,如果我尝试使用该片段中的任何导航操作,则会出现错误:
java.lang.IllegalArgumentException: navigation destination com.example.test/actionNavigateToNextFragment 对此 NavController 未知
如果我可以访问NavController
中的mBackStack
字段,这可以解决,但它package private
,并且我不能在当前项目中使用反射。但如果是public
,我会按以下方式使用它:
override fun onBackPressed() {
// 2 because first one is NavGraph, second one is last fragment on the stack
if(navController.mBackStack.size > 2) {
navController.navigateUp()
return
}
showQuitDialog()
}
有没有办法不反思地做到这一点?
您可以将起始目标的 ID 与当前目标的 ID 进行比较。像这样:
override fun onBackPressed() = when {
navController.graph.startDestination == navController.currentDestination?.id -> showQuitDialog()
else -> super.onBackPressed()
}
希望对您有所帮助。
对任何目的地尝试此操作(您可以在导航图中找到您的目的地 ID(:
private fun isDesiredDestination(): Boolean {
return with(navController) {
currentDestination == graph[R.id.yourDestinationId]
}
}
比较目标的 ID 可能不是最佳解决方案,因为您可能有多个具有相同 ID 但反向堆栈上具有不同参数的屏幕。
这是一个替代方案:
val isRootScreen = navController.previousBackStackEntry == null
如果你想要这是一个按钮,可以这么说你可以拥有这个
yourbutton.setOnClickListener {
val currentFragment = navController.currentDestination?.id
when (navController.graph.startDestination == currentFragment) {
true -> { //Go here}
// Go to the app home
else -> onBackPressed()
}
}