I'm implementing the new model of the Android NavHost navigation system. However, I can not resolve how to apply the custom transition animation,
Here's my implemented navhost,
AndroidNavigationTheme {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = HomeScreen,
){
composable<HomeScreen>{
HomeScreen(
onClickGoAboutScreen = {
navController.navigate(AboutScreen)
}
)
}
composable<AboutScreen>{
AboutScreen(
onClickGoContentScreen = {
navController.navigate(ContentScreen)
}
)
}
composable<ContentScreen>{
ContentScreen(
onClickGoHomeScreen = {
navController.navigate(HomeScreen)
}
)
}
}
}
@Serializable
object HomeScreen
@Serializable
object AboutScreen
@Serializable
object ContentScreen
And here's my code for the transition animation,
fun scaleIntoContainer(
direction: ScaleTransitionDirection = ScaleTransitionDirection.INWARDS,
initialScale: Float = if (direction == ScaleTransitionDirection.OUTWARDS) 0.9f else 1.1f
): EnterTransition {
return scaleIn(
animationSpec = tween(220, delayMillis = 90),
initialScale = initialScale
) + fadeIn(animationSpec = tween(220, delayMillis = 90))
}
fun scaleOutOfContainer(
direction: ScaleTransitionDirection = ScaleTransitionDirection.OUTWARDS,
targetScale: Float = if (direction == ScaleTransitionDirection.INWARDS) 0.9f else 1.1f
): ExitTransition {
return scaleOut(
animationSpec = tween(
durationMillis = 220,
delayMillis = 90
), targetScale = targetScale
) + fadeOut(tween(delayMillis = 90))
}
enum class ScaleTransitionDirection {
INWARDS,
OUTWARDS
}
I'm not too fond of the default transition that the Navhost provided, If possible also suggest some good transition animation too.
The new typesafe composable
function still offers parameters for custom transitions:
inline fun <T : Any> NavGraphBuilder.composable(
typeMap: Map<KType, NavType<*>> = emptyMap(),
deepLinks: List<NavDeepLink> = emptyList(),
noinline enterTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition)? = null,
noinline exitTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition)? = null,
noinline popEnterTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition)? = enterTransition,
noinline popExitTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition)? = exitTransition,
noinline sizeTransform: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform)? = null,
noinline content: @Composable AnimatedContentScope.(NavBackStackEntry) -> Unit
): Unit
You can simply apply them as follows:
composable<HomeScreen>(
enterTransition = {
scaleIntoContainer()
},
exitTransition = {
scaleOutOfContainer()
}
) {
HomeScreen(
onClickGoAboutScreen = {
navController.navigate(AboutScreen)
}
)
}
If the animation does not occur in your case, please double-check your animation and how you are calling it. I just verified with these two simple animations that it works on androidx.navigation:navigation-compose:2.8.1
:
fun scaleIntoContainer(): EnterTransition {
return slideInHorizontally(
animationSpec = tween(2000),
initialOffsetX = { fullWidth -> fullWidth }
)
}
fun scaleOutOfContainer(): ExitTransition {
return slideOutHorizontally(
animationSpec = tween(2000),
targetOffsetX = { fullWidth -> -fullWidth }
)
}