撰写导航 - 替换起始路线并清除返回堆栈

Compose navigation - replace starting route and clear back stack

我正在使用 JetPack Compose 和可组合的 NavHost。

我有一个场景,我需要一个连接蓝牙设备的启动屏幕,所以我在 NavHost 中将其设置为我的起始路线。

连接完成后,我想进入主屏幕,再也不想回到启动屏幕。

所以在连接完成后启动屏幕我正在这样做:

   navController.graph.setStartDestination(newHomeRoute)
   navController.navigate(newHomeRoute) {
      popUpTo(0)
      launchSingleTop = true
   }

这不起作用,因为我不断循环返回到 LaunchScreen 并转发到 Home。

也许我应该用其他方式做到这一点?

据我所知,您不能在 Jetpack Navigation 中执行此操作(对于片段和组合)

我确实遇到了这个问题。

在这里分享我的代码。

简答,

navHostController.popBackStack("routeOfLaunchingScreen", true)
navHostController.navigate("newHomeRoute")
            

true 表示弹出堆栈直到并包括给定的路由。 根据需要弹出返回堆栈后,我们导航到新屏幕。

希望这能解决您的问题。 :)

长答案(复制粘贴解决方案)

MyNavActions.

class MyNavActions(navHostController: NavHostController) {
    val navigateTo = { navBackStackEntry: NavBackStackEntry, route: String ->
        if (navBackStackEntry.lifecycleIsResumed()) {
            navHostController.navigate(route)
        }
    }

    val navigateUp = { navBackStackEntry: NavBackStackEntry ->
        if (navBackStackEntry.lifecycleIsResumed()) {
            navHostController.navigateUp()
        }
    }

    val popBackStackAndNavigate =
        { navBackStackEntry: NavBackStackEntry, route: String?, popUpTo: String, inclusive: Boolean ->
            if (navBackStackEntry.lifecycleIsResumed()) {
                navHostController.popBackStack(popUpTo, inclusive)
                route?.let {
                    navHostController.navigate(route)
                }
            }
        }
    }
}

/**
 * If the lifecycle is not resumed it means this NavBackStackEntry already processed a nav event.
 *
 * This is used to de-duplicate navigation events.
 */
private fun NavBackStackEntry.lifecycleIsResumed() =
    this.lifecycle.currentState == Lifecycle.State.RESUMED

用法

val myNavActions = remember(navHostController) {
    MyNavActions(navHostController)
}

返回堆栈直到给定路线并导航

chcNavActions.popBackStackAndNavigate(
    navBackStackEntry,
    routeToPopUpTo,
    routeToNavigateTo,
    true, // inclusive flag - boolean denoting if the specified route `routeToPopUpTo` should also be popped
)

返回导航

chcNavActions.navigateUp(navBackStackEntry)

简单导航

chcNavActions.navigateTo(navBackStackEntry, route)

我设法用这样的扩展来做到这一点:

fun NavHostController.navigateAndReplaceStartRoute(newHomeRoute: String) {
    popBackStack(graph.startDestinationId, true)
    graph.setStartDestination(newHomeRoute)
    navigate(newHomeRoute)
}