检查导航图是否位于返回堆栈上

Flo*_*her 9 navigation android android-architecture-components android-architecture-navigation

我的导航图有一个auth包含 LoginFragment 和 SignUpFragment 的子图:

<navigation
    android:id="@+id/auth"
    app:startDestination="@id/loginFragment">
    <fragment
        android:id="@+id/signUpFragment"
        [...]
    <fragment
        android:id="@+id/loginFragment"
        [...]
    </fragment>
    [...]
</navigation>
Run Code Online (Sandbox Code Playgroud)

我想检查这两个目的地中的任何一个当前是否位于返回堆栈上。但不要单独检查每个目的地,如下所示:

val currentDestId = navController.currentDestination?.id
if (currentDestId != R.id.loginFragment && currentDestId != R.id.signUpFragment) {
    navController.navigate(
        NavGraphDirections.actionGlobalLogin()
    )
}
Run Code Online (Sandbox Code Playgroud)

我认为只检查身份验证图当前是否位于返回堆栈上会更干净。

我目前的方法如下:

val authBackStack = try {
    navController.getBackStackEntry(R.id.auth)
} catch (t: Throwable) {
    null
}
if (authBackStack == null) {
    navController.navigate(
        NavGraphDirections.actionGlobalLogin()
    )
}
Run Code Online (Sandbox Code Playgroud)

这里的想法是,如果传递的目标(或本例中的图形)当前不在返回堆栈上,则getBackStackEntry抛出异常。IllegalStateException我们使用此异常作为指示器来查明我们的图形当前是否位于返回堆栈上。

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

Epi*_*rce 11

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

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

这样,您实际上可以获得所需的布尔值,同时隐藏基于异常的控制流(这是 Jetpack Navigation 公开的 API 的要求)。