【问题标题】:Check if a navigation graph is on the backstack检查导航图是否在 backstack 上
【发布时间】:2021-01-01 11:11:16
【问题描述】:

我的导航图有一个 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 如果传递的目的地(或本例中的图形)当前不在后堆栈上。我们使用这个异常作为一个指标来判断我们的图当前是否在后栈中。

这是一种有效的方法还是会在某些情况下失效?或者也许有更好的方法来检查返回堆栈是否包含某个子图的目的地?

【问题讨论】:

  • 也许这会有所帮助。 popBackStack 返回布尔值。根据结果​​,我们知道目的地是否在堆栈上。 val hasAuthDestionation = findNavController().popBackStack(R.id.auth, false) if (!hasAuthDestionation) { findNavController().navigate(R.id.newDestination) } 另外,如果需要,您可以使用包容性 'true'。

标签: android navigation android-architecture-components android-architecture-navigation


【解决方案1】:

这是正确的方法,但您可以将其隐藏为扩展函数,如下所示:

fun NavController.isOnBackStack(@IdRes id: Int): Boolean = try { getBackStackEntry(id); true } catch(e: Throwable) { false }

这样你实际上得到了你想要的布尔值,同时隐藏了基于异常的控制流(这是由于 Jetpack Navigation 公开的 API 的要求)。

【讨论】:

    猜你喜欢
    • 2018-11-17
    • 2012-12-31
    • 2021-01-19
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 2015-06-27
    相关资源
    最近更新 更多