如何在Android Jetpack Compose中为NavHost添加自定义过渡动画
一、应用你已实现的缩放过渡动画
只需在NavHost的composable函数中,通过enterTransition和exitTransition参数指定自定义动画即可;如果需要返回栈时的反向动画,可补充popEnterTransition和popExitTransition参数:
修改后的NavHost代码示例:
AndroidNavigationTheme { val navController = rememberNavController() NavHost( navController = navController, startDestination = HomeScreen, ){ composable<HomeScreen>( enterTransition = { scaleIntoContainer() }, exitTransition = { scaleOutOfContainer() }, // 返回Home页面时的反向动画 popEnterTransition = { scaleIntoContainer(ScaleTransitionDirection.OUTWARDS) }, popExitTransition = { scaleOutOfContainer(ScaleTransitionDirection.INWARDS) } ){ HomeScreen( onClickGoAboutScreen = { navController.navigate(AboutScreen) } ) } composable<AboutScreen>( enterTransition = { scaleIntoContainer() }, exitTransition = { scaleOutOfContainer() }, popEnterTransition = { scaleIntoContainer(ScaleTransitionDirection.OUTWARDS) }, popExitTransition = { scaleOutOfContainer(ScaleTransitionDirection.INWARDS) } ){ AboutScreen( onClickGoContentScreen = { navController.navigate(ContentScreen) } ) } composable<ContentScreen>( enterTransition = { scaleIntoContainer() }, exitTransition = { scaleOutOfContainer() }, popEnterTransition = { scaleIntoContainer(ScaleTransitionDirection.OUTWARDS) }, popExitTransition = { scaleOutOfContainer(ScaleTransitionDirection.INWARDS) } ){ ContentScreen( onClickGoHomeScreen = { navController.navigate(HomeScreen) } ) } } }
参数说明:
enterTransition:从其他页面导航到当前页面的进入动画exitTransition:从当前页面导航到其他页面时的退出动画popEnterTransition:从返回栈回到当前页面时的进入动画(如点击返回键)popExitTransition:从当前页面返回上一页时的退出动画
二、推荐其他优质过渡动画
如果想尝试不同风格的页面切换效果,以下几种动画可以参考:
1. 左右滑动过渡(原生风格)
适合大多数常规页面切换,模拟原生Android的滑动逻辑:
fun slideInFromRight(): EnterTransition { return slideInHorizontally( animationSpec = tween(300), initialOffsetX = { it } // 从屏幕右侧外进入 ) + fadeIn(tween(300)) } fun slideOutToLeft(): ExitTransition { return slideOutHorizontally( animationSpec = tween(300), targetOffsetX = { -it } // 滑到屏幕左侧外 ) + fadeOut(tween(300)) } // 返回时的反向动画 fun slideInFromLeft(): EnterTransition { return slideInHorizontally( animationSpec = tween(300), initialOffsetX = { -it } ) + fadeIn(tween(300)) } fun slideOutToRight(): ExitTransition { return slideOutHorizontally( animationSpec = tween(300), targetOffsetX = { it } ) + fadeOut(tween(300)) }
2. 淡入淡出过渡
简洁优雅,适合轻量级页面切换:
fun fadeInTransition(): EnterTransition { return fadeIn(animationSpec = tween(300)) } fun fadeOutTransition(): ExitTransition { return fadeOut(animationSpec = tween(300)) }
3. 旋转缩放组合过渡
适合特殊场景(如详情页、弹窗类页面):
fun rotateScaleEnter(): EnterTransition { return rotateIn( animationSpec = tween(300), initialAngle = 180f ) + scaleIn( animationSpec = tween(300), initialScale = 0.5f ) + fadeIn(tween(300)) } fun rotateScaleExit(): ExitTransition { return rotateOut( animationSpec = tween(300), targetAngle = 180f ) + scaleOut( animationSpec = tween(300), targetScale = 0.5f ) + fadeOut(tween(300)) }
4. 底部滑入过渡
适合底部弹窗、全屏详情页等场景:
fun slideInFromBottom(): EnterTransition { return slideInVertically( animationSpec = tween(300), initialOffsetY = { it } ) + fadeIn(tween(300)) } fun slideOutToBottom(): ExitTransition { return slideOutVertically( animationSpec = tween(300), targetOffsetY = { it } ) + fadeOut(tween(300)) }
三、进阶技巧
可以根据导航方向动态切换动画,比如通过navBackStackEntry判断前进/后退状态,自动应用对应动画:
composable<AboutScreen>( enterTransition = { if (initialState.destination.route == HomeScreen::class.simpleName) { slideInFromRight() } else { scaleIntoContainer() } } ) { // 页面内容 }
内容的提问来源于stack exchange,提问作者Mehedi Hasan
相关产品推荐
相关产品推荐

