Jetpack Compose如何动态修改同一目标页面的导航动画?
在Jetpack Compose中为同一页面设置不同导航动画
要实现同一目标页面在不同场景下使用不同导航动画,核心思路是通过路由参数传递动画类型标识,并在页面的过渡配置中根据该标识动态选择对应的动画效果。以下是具体实现步骤:
1. 定义动画类型枚举(可选但推荐)
创建枚举类统一管理动画类型,避免字符串硬编码:
enum class ScreenAnimation { HORIZONTAL, // 右侧滑入 VERTICAL // 底部滑入 }
2. 修改路由配置,添加动画参数
在composable配置中为路由添加可选动画参数,并设置默认值:
composable( route = "Details?animation={animation}", arguments = listOf( navArgument("animation") { type = NavType.EnumType(ScreenAnimation::class) defaultValue = ScreenAnimation.VERTICAL // 默认使用底部滑入动画 nullable = false } ), deepLinks = listOf(navDeepLink { uriPattern = "myapp://test/details?animation={animation}" }), enterTransition = { // 从目标页面参数中获取动画类型 val animationType = targetState.arguments?.getSerializable("animation") as? ScreenAnimation ?: ScreenAnimation.VERTICAL when (animationType) { ScreenAnimation.HORIZONTAL -> slideInHorizontally( initialOffsetX = { it }, animationSpec = tween(durationMillis = 700, easing = LinearOutSlowInEasing) ) ScreenAnimation.VERTICAL -> slideInVertically( initialOffsetY = { it }, animationSpec = tween(durationMillis = 700, easing = LinearOutSlowInEasing) ) } }, exitTransition = { ExitTransition.None }, popEnterTransition = { EnterTransition.None }, popExitTransition = { // 从当前页面(即将弹出的页面)参数中获取动画类型 val animationType = initialState.arguments?.getSerializable("animation") as? ScreenAnimation ?: ScreenAnimation.VERTICAL when (animationType) { ScreenAnimation.HORIZONTAL -> slideOutHorizontally( targetOffsetX = { it }, animationSpec = tween(durationMillis = 700, easing = LinearOutSlowInEasing) ) ScreenAnimation.VERTICAL -> slideOutVertically( targetOffsetY = { it }, animationSpec = tween(durationMillis = 700, easing = LinearOutSlowInEasing) ) } } ) { backStackEntry -> // 若需在Composable中使用动画类型,可从backStackEntry获取 // val animationType = backStackEntry.arguments?.getSerializable("animation") as ScreenAnimation MyComposable() }
3. 不同场景下的导航调用
- 普通场景(右侧滑入):
navController.navigate("Details?animation=${ScreenAnimation.HORIZONTAL.name}")
- 通知跳转场景(底部滑入):
navController.navigate("Details?animation=${ScreenAnimation.VERTICAL.name}")
- Deep Link跳转:
使用带参数的URI即可,例如:myapp://test/details?animation=HORIZONTAL
关键说明
- 路由参数会保留在回退栈中,返回时的动画会与进入时保持一致。
- 枚举类型可避免字符串拼写错误,提升代码健壮性。
- 若不需要对外暴露动画参数,也可通过ViewModel或CompositionLocal临时传递,但路由参数方式更可靠(支持进程恢复场景)。
内容的提问来源于stack exchange,提问作者androiddev321
相关产品推荐
相关产品推荐

