撰写导航 - 替换起始路线并清除返回堆栈
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)
}
我正在使用 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)
}