在 Android 导航架构中,如何检查当前片段是否是最后一个片段?
In Android Navigation Architecture, how can I check if current Fragment is the last one?
我需要显示自定义 AlertDialog
,但只有在调用 NavController.navigateUp()
后没有更多片段时才会显示。我当前的代码做了类似的事情,但是有一个错误:
override fun onBackPressed() {
if (navController.navigateUp()) {
return
}
showQuitDialog()
}
这有点管用,但是如果我取消 AlertDialog
并且不退出应用程序,navController
已经导航到 NavGraph
root,这不是其中的片段我在AlertDialog
出现的时候。因此,如果我尝试使用该片段中的任何导航操作,我会收到错误消息:
java.lang.IllegalArgumentException: navigation destination
com.example.test/actionNavigateToNextFragment is unknown to this 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]
}
}
如果你想要这是一个按钮,可以这么说,你可以拥有这个
yourbutton.setOnClickListener {
val currentFragment = navController.currentDestination?.id
when (navController.graph.startDestination == currentFragment) {
true -> { //Go here}
// Go to the app home
else -> onBackPressed()
}
}
比较目标 ID 可能不是最佳解决方案,因为您可能有多个屏幕具有相同的 ID,但后台堆栈中的参数不同。
这是一个替代方案:
val isRootScreen = navController.previousBackStackEntry == null
我需要显示自定义 AlertDialog
,但只有在调用 NavController.navigateUp()
后没有更多片段时才会显示。我当前的代码做了类似的事情,但是有一个错误:
override fun onBackPressed() {
if (navController.navigateUp()) {
return
}
showQuitDialog()
}
这有点管用,但是如果我取消 AlertDialog
并且不退出应用程序,navController
已经导航到 NavGraph
root,这不是其中的片段我在AlertDialog
出现的时候。因此,如果我尝试使用该片段中的任何导航操作,我会收到错误消息:
java.lang.IllegalArgumentException: navigation destination com.example.test/actionNavigateToNextFragment is unknown to this 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]
}
}
如果你想要这是一个按钮,可以这么说,你可以拥有这个
yourbutton.setOnClickListener {
val currentFragment = navController.currentDestination?.id
when (navController.graph.startDestination == currentFragment) {
true -> { //Go here}
// Go to the app home
else -> onBackPressed()
}
}
比较目标 ID 可能不是最佳解决方案,因为您可能有多个屏幕具有相同的 ID,但后台堆栈中的参数不同。
这是一个替代方案:
val isRootScreen = navController.previousBackStackEntry == null