You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android Jetpack Compose中为NavHost添加自定义过渡动画

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 21:57:12