android - 检查导航图是否在 backstack 上
问题描述
我的导航图有一个auth
包含 LoginFragment 和 SignUpFragment 的子图:
<navigation
android:id="@+id/auth"
app:startDestination="@id/loginFragment">
<fragment
android:id="@+id/signUpFragment"
[...]
<fragment
android:id="@+id/loginFragment"
[...]
</fragment>
[...]
</navigation>
我想检查这两个目的地中的任何一个当前是否在后台。但不是单独检查每个目的地,如下所示:
val currentDestId = navController.currentDestination?.id
if (currentDestId != R.id.loginFragment && currentDestId != R.id.signUpFragment) {
navController.navigate(
NavGraphDirections.actionGlobalLogin()
)
}
我认为只检查身份验证图当前是否在后堆栈上会更干净。
我目前的方法如下:
val authBackStack = try {
navController.getBackStackEntry(R.id.auth)
} catch (t: Throwable) {
null
}
if (authBackStack == null) {
navController.navigate(
NavGraphDirections.actionGlobalLogin()
)
}
这里的想法是,如果传递的目的地(或本例中的图形)当前不在后堆栈上,则getBackStackEntry
抛出一个。IllegalStateException
我们使用这个异常作为一个指标来确定我们的图当前是否在后栈中。
这是一种有效的方法还是会在某些情况下中断?或者也许有更好的方法来检查后堆栈是否包含某个子图的目的地?
解决方案
这是正确的方法,但您可以将其隐藏为扩展函数,如下所示:
fun NavController.isOnBackStack(@IdRes id: Int): Boolean = try { getBackStackEntry(id); true } catch(e: Throwable) { false }
这样你实际上得到了你想要的布尔值,同时隐藏了基于异常的控制流(这是由于 Jetpack Navigation 公开的 API 的要求)。
推荐阅读
- sql - 如何在雪花中将字符串拆分为字符?
- report - 如何从命令提示符生成 Oracle Reports 的 PDF 文件?
- javascript - 是否可以在服务器的 PHP 代码中生成的 AJAX 响应中执行 JavaScript?
- c# - NPOI:更改单元格中某些(不是全部)文本的字体颜色
- terminal - macOS 10.15 终端 - 取消链接得到“不允许操作”
- azure - OAUTH 流 - 事件中心
- ansible - Ansible 从 ansbile 事实值中删除引用
- sql - SQL:递归 CTE 的执行模型
- java - 在 NEXUS5X 29API 中找不到 TYPE_STEP_COUNTER 传感器
- java - 从 Windows 连接到远程 mysql 数据库