Have an Activity
which holds NavHostController
, when activity starts, need to navigate X screen, but pressing back need to navigate to previous screen, not to the start destination (because navigating to X was from startDest).
@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"
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)
Question: How to set back stack history in nav controller OR How navigate (jump) with keeping back stack order.
OK actually solved this issue using view-pager see here
So It can jump easily any screen on View-pager as current page,
LaunchedEffect(
key1 = currentPage,
block = {
pagerState.animateScrollToPage(currentPage)
})
and overrides back button and action to go back through view-pager pages (currentPage-1) if current page. is 0, then closes whole screen (activity).
Also disabled user events on view-pager to not allow change page with swiping, set userScrollEnabled
to false.
userScrollEnabled: Boolean = false
BUT Second solution using navigation.
private const val STEPS: String = "steps"
private const val CURRENT_STEP: String = "currentStep"
private const val PATH: String = "your_screen/{$STEPS}/{$CURRENT_STEP}"
@Composable
fun MyComposable() {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = PATH,
modifier = modifier.fillMaxSize(),
) {
composable(
route = PATH,
arguments = listOf(
navArgument(CURRENT_STEP) {
type = NavType.IntType
defaultValue = 0
},
)
) { backStackEntry ->
PagesScreen(
navController = navController,
currentStep = backStackEntry.arguments?.getInt(CURRENT_STEP) ?: 0,
)
}
}
}
@Composable
private fun PagesScreen(
navController: NavController,
modifier: Modifier = Modifier,
currentStep: Int = 0,
onFinish: () -> Unit = {},
) {
val stepsCount = 6 // your navigation steps pages count
// show current page
val goToNextScreen = {
if (currentStep < stepsCount - 1) {
navController.navigate("your_screen/$stepsCount/${currentStep + 1}")
} else {
onFinish()
}
}
val goToPreviousScreen = {
if (currentStep > 0) {
navController.navigate("your_screen/$stepsCount/${currentStep - 1}")
} else {
onFinish()
}
}
}