[英]Jetpack Compose: navigate to X screen (jump) keeping back-stack history
Have Activity
which holds NavHostController
, when activity starts need to navigate X screen but pressing back need to navigate to previous screen not to start destination.拥有包含
NavHostController
的Activity
,当 Activity 开始时需要导航 X 屏幕但按下返回需要导航到上一个屏幕而不是开始目的地。
@OptIn(ExperimentalMaterialNavigationApi::class)
@Composable
private fun NavHostController(
navController: NavHostController,
startDest: String = "screen 1"
) {
NavHost(
navController = navController,
startDestination = startDest,
) {
composable("screen 1") {}
composable("screen 2") {}
...
composable("screen N") {}
}}
EXAMPLE:例子:
have screens like: "screen 1-2-3-4-5..N"有这样的屏幕:“屏幕 1-2-3-4-5..N”
and the "screen 1" is start destination, activity starts and nav-ctrl jumps to screen 5(for example), and the back press need to work like: to 4, 3, 2.. NOT direct 1 (as start destination is 1)并且“屏幕1”是开始目的地,活动开始并且nav-ctrl跳转到屏幕5(例如),并且后按需要像:到4、3、2..而不是直接1(因为开始目的地是1)
Question: How to set back stack history in nav controller OR How navigate (jump) with keeping back stack order.问题:如何在导航 controller 中设置回退堆栈历史记录或如何在保持回退堆栈顺序的情况下导航(跳转)。
To achieve this you will need to use the BackHandler
and make some check to see if the previous back stack route is the screen that should be the destination when using the back button.为了实现这一点,您需要使用
BackHandler
并检查前一个返回堆栈路由是否是使用返回按钮时应该成为目的地的屏幕。 For example:例如:
@Composable
fun ScreenOne(
nextScreen: () -> Unit
) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "ScreenOne")
Button(onClick = nextScreen) {
Text(text = "Next")
}
}
}
@Composable
fun ScreenTwo(
back: () -> Unit,
nextScreen: () -> Unit
) {
// to intercept the click on the back button of the android navigation bar
BackHandler(onBack = back)
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "ScreenTwo")
Button(onClick = back) {
Text(text = "Back")
}
Button(onClick = nextScreen) {
Text(text = "Next")
}
}
}
@Composable
fun ScreenThree(
back: () -> Unit
) {
// to intercept the click on the back button of the android navigation bar
BackHandler(onBack = back)
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "ScreenThree")
Button(onClick = back) {
Text(text = "Back")
}
}
}
ScreenOne
just have the option to navigate to ScreenTwo
. ScreenOne
只能选择导航到ScreenTwo
。
ScreenTwo
have the option to navigate (back) to ScreenOne
and navigate to ScreenThree
. ScreenTwo
可以选择导航(返回)到ScreenOne
并导航到ScreenThree
。
ScreenThree
just have the option to navigate (back) to ScreenTwo
. ScreenThree
只能选择导航(返回)到ScreenTwo
。
Extension to navigate back:向后导航的扩展:
fun NavHostController.navigateBack(
targetRoute: String,
currentRoute: String
) {
val previousRoute = previousBackStackEntry?.destination?.route ?: "null"
// if the previous route is what we want, just go back
if (previousRoute == targetRoute) popBackStack()
// otherwise, we do the navigation explicitly
else navigate(route = targetRoute) {
// remove the entire backstack up to this this route, including herself
popUpTo(route = currentRoute) { inclusive = true }
launchSingleTop = true
}
}
NavHost:导航主机:
NavHost(
modifier = Modifier.fillMaxSize(),
navController = navController,
startDestination = "screen_three"
) {
composable(route = "screen_one") {
ScreenOne(
nextScreen = {
navController.navigate(route = "screen_two") {
launchSingleTop = true
}
}
)
}
composable(route = "screen_two") {
ScreenTwo(
back = {
navController.navigateBack(
targetRoute = "screen_one",
currentRoute = "screen_two"
)
},
nextScreen = {
navController.navigate(route = "screen_three") {
launchSingleTop = true
}
}
)
}
composable(route = "screen_three") {
ScreenThree(
back = {
navController.navigateBack(
targetRoute = "screen_two",
currentRoute = "screen_three"
)
}
)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.