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

mis*_*iac 10 android android-jetpack-navigation android-jetpack-compose

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

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

连接完成后,我想进入主屏幕,并且永远不会返回到启动屏幕。

因此,连接完成后启动屏幕我正在这样做:

   navController.graph.setStartDestination(newHomeRoute)
   navController.navigate(newHomeRoute) {
      popUpTo(0)
      launchSingleTop = true
   }
Run Code Online (Sandbox Code Playgroud)

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

那么也许我应该以其他方式做到这一点?

Abh*_*bhi 8

我遇到了这个问题。

在这里分享我的代码。

简短回答

navHostController.popBackStack("routeOfLaunchingScreen", true)
navHostController.navigate("newHomeRoute")
            
Run Code Online (Sandbox Code Playgroud)

表示true弹出堆栈直到并包括给定的路线。一旦按要求弹出返回堆栈,我们就会导航到新屏幕。

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

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

我的导航操作

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
Run Code Online (Sandbox Code Playgroud)

用法

val myNavActions = remember(navHostController) {
    MyNavActions(navHostController)
}
Run Code Online (Sandbox Code Playgroud)

弹出堆栈直到给定路线并导航

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

返回导航

chcNavActions.navigateUp(navBackStackEntry)
Run Code Online (Sandbox Code Playgroud)

简单的导航

chcNavActions.navigateTo(navBackStackEntry, route)
Run Code Online (Sandbox Code Playgroud)


mis*_*iac 7

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

fun NavHostController.navigateAndReplaceStartRoute(newHomeRoute: String) {
    popBackStack(graph.startDestinationId, true)
    graph.setStartDestination(newHomeRoute)
    navigate(newHomeRoute)
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*ele 7

您可以使用此扩展:

fun NavHostController.navigateAndClean(route: String) {
    navigate(route = route) {
        popUpTo(graph.startDestinationId) { inclusive = true }
    }
    graph.setStartDestination(route)
}
Run Code Online (Sandbox Code Playgroud)