I would like to have different navigation animations for the same page, but for different navigation scenarios. E.g.
Practical scenario is e.g. page1 is one of the page from bottomNavigationBar. page5 is a page to update some properties from the page1. I want to highlite by using different navigation animations that page1 is the main one, and page5 is the secondary.
So I faced with the following issue. I cannot find robust solution to get "previous" and "next" page names. The code bock below is the enterTransition for page1 with condition operator to support different animations based on previous page name.
enterTransition = { //enterTransition for page1
when("previousPageName") {
"page1" -> fadeIn(animationSpec = tween(delayMillis = 250)) + slideInHorizontally(initialOffsetX = {-it}, animationSpec = tween(delayMillis = 150, durationMillis = 200))
"page2" -> fadeIn() + slideInHorizontally()
else -> fadeIn()
}
}
to get previous page name, apparently, the best way is to use NavigationController, so the sample above can be rewritten.
enterTransition = { //enterTransition for page1
when(**navController.previousBackStackEntry!!.destination.route**) {
"page1" -> fadeIn(animationSpec = tween(delayMillis = 250)) + slideInHorizontally(initialOffsetX = {-it}, animationSpec = tween(delayMillis = 150, durationMillis = 200))
"page2" -> fadeIn() + slideInHorizontally()
else -> fadeIn()
}
}
I've expected to find name of previous page there anytime. But practically, in the case when navigation is done with navigationController.popUpBackStack() e.g. clicking on "return back" button. It removes/breaks navController.previousBackStackEntry and as a result it contains a page I do not expect e.g. "page3". And I can understand such behavior, it operates with BackStack, but if so, I have no idea how to manage different animations between different pages based on a navigation graph state. One possible solution could be to have/manage a variable to store previous page, but that is the last I will use to achieve my goals. It would be nice to find more elegant solution.
So I have a couple questions:
popUpBackStack()
ornavController.navigate("page1") {
popUpTo(
"page5"
) { inclusive = true }
}
Thank you in advance for help.
Tried to get previous page from navigationController.previousBackStackEntry but without needed result
As explained in the Animations in Navigation Compose blog post, each transition lambda is in the format of:
enterTransition: (
AnimatedContentScope<NavBackStackEntry>.() -> EnterTransition?
)? = null,
Which, as it explains:
That lambda uses the
AnimatedContentScope
to provide you with theNavBackStackEntry
of where you are coming from (theinitialState
) and where you are going to (thetargetState
). For example, for theenterTransition
, the entering destination is thetargetState
— the one you are applying theenterTransition
to.
Which lets you write your code such as:
enterTransition = {
// initialState is the screen you are coming from (the one leaving)
// targetState is the screen you are going to (the one entering)
when(initialState.destination.route) {
"page1" -> fadeIn(animationSpec = tween(delayMillis = 250)) + slideInHorizontally(initialOffsetX = {-it}, animationSpec = tween(delayMillis = 150, durationMillis = 200))
"page2" -> fadeIn() + slideInHorizontally()
else -> fadeIn()
}
}