Animated Style pass custom variable
See original GitHub issueAmazing work with the library, it really makes things easier!
One question, if you want animations between screen you can create custom style for each screen that overrides the default AnimatedNavHostEngine
you can define for all screens in that graph. But in styles I can’t seem to find a way to pass a variable to it. For example in the documentation under ProfileTransitions.kt
you have hardcoded initialOffsetX = 1000
, but what if I wanted a different number (for example the exact width of the screen. I can define this for default animations, but not for each individual screen.
For example:
ProvideWindowInsets {
AppTheme {
val navController = rememberAnimatedNavController()
val viewModel: CustomViewModel = hiltViewModel()
// We can get width of the screen this way
BoxWithConstraints {
val width = constraints.maxWidth
val navHostEngine = rememberAnimatedNavHostEngine(
rootDefaultAnimations = RootNavGraphDefaultAnimations(
enterTransition = {
slideInHorizontally(
initialOffsetX = { width },
animationSpec = tween(
durationMillis = 700,
easing = FastOutSlowInEasing
)
)
},
exitTransition = {
slideOutHorizontally(
targetOffsetX = { -width },
animationSpec = tween(
durationMillis = 700,
easing = FastOutSlowInEasing
)
)
},
popEnterTransition = {
slideInHorizontally(
initialOffsetX = { -width },
animationSpec = tween(
durationMillis = 700,
easing = FastOutSlowInEasing
)
)
},
popExitTransition = {
slideOutHorizontally(
targetOffsetX = { width },
animationSpec = tween(
durationMillis = 700,
easing = FastOutSlowInEasing
)
)
}
),
)
DestinationsNavHost(
navGraph = NavGraphs.root,
startRoute = NavGraphs.root.startRoute,
engine = navHostEngine,
navController = navController,
modifier = Modifier
) {
animatedComposable(AScreenDestination) {
AScreen(
modifier = Modifier.statusBarsPadding(),
viewModel = viewModel,
)
}
animatedComposable(BScreenDestination) {
BScreen(
modifier = Modifier.statusBarsPadding(),
viewModel = viewModel,
)
}
}
}
}
}
In this case both will have default, then If I wanted to change the transition of BScreen
, you would need to add:
object BScreenTransition: DestinationStyle.Animated {
override fun AnimatedContentScope<NavBackStackEntry>.enterTransition(): EnterTransition? {
return when (initialState.navDestination) {
BScreenTransitionDestination ->
slideInHorizontally(
initialOffsetX = { 1000 },
animationSpec = tween(2500)
)
else -> null
}
}
override fun AnimatedContentScope<NavBackStackEntry>.exitTransition(): ExitTransition? {
return when (targetState.navDestination) {
BScreenTransitionDestination ->
slideOutHorizontally(
targetOffsetX = { -1000 },
animationSpec = tween(2500)
)
else -> null
}
}
override fun AnimatedContentScope<NavBackStackEntry>.popEnterTransition(): EnterTransition? {
return when (initialState.navDestination) {
BScreenTransitionDestination ->
slideInHorizontally(
initialOffsetX = { -1000 },
animationSpec = tween(2500)
)
else -> null
}
}
override fun AnimatedContentScope<NavBackStackEntry>.popExitTransition(): ExitTransition? {
return when (targetState.navDestination) {
BScreenTransitionDestination ->
slideOutHorizontally(
targetOffsetX = { 1000 },
animationSpec = tween(2500)
)
else -> null
}
}
}
Then in BScreen add:
@Destination(
style = BScreenTransition::class,
)
So the animation style would be applied.
This way you can’t pass the width
to the BScreenTransition
you can only change a fixed number inside this object.
Maybe it can be done and I just don’t know how.
Thanks for the help!
Issue Analytics
- State:
- Created 2 years ago
- Comments:6 (3 by maintainers)
First of all, amazing work and amazing library!
I’ve tinkered a bit with it for the past few days, and I’ve also encountered this issue. A quick and dirty fix might be to use the android system resources to get the screen width/height:
The only issue here is that the
DisplayMetrics
don’t account for the sizes of system bars, like the navigation bar and the top system bar. For horizontal transitions this is fine(I don’t think there are any system bars impacting the width of the screen), but forheight
based transitions this is something to be aware of.I will check a way to get screen size in all transitions then 🙂 Tbh I focused only on samples to get the current animations APIs, so I’m glad you’re trying them so I can iterate on your feedback!
I’ll leave this open until I have time to check it.