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

如何在Jetpack Compose中实现屏幕间流畅的导航动画过渡?

Jetpack Compose 导航动画修复方案

问题描述

在Jetpack Compose应用中构建导航流程时,从StartScreen导航至LoginScreen时,StartScreen会覆盖LoginScreen,无法实现目标的屏幕间流畅滑动过渡(目标效果:StartScreen向左完全滑出,LoginScreen从右侧同步滑入)。调整initialOffset数值后仍未解决问题。

当前代码实现

@Composable
fun MyAppNavigation(
    modifier: Modifier, authViewModel: AuthViewModel
) {

    val navController = rememberNavController()
    NavHost(navController = navController, startDestination = "start") {
        composable(route = "start",
            enterTransition = {
                slideInHorizontally(
                    initialOffsetX = { -500 }, // small slide 300px
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = FastOutSlowInEasing // interpolator
                    )
                )
            },
            exitTransition = {
                slideOutHorizontally(
                    targetOffsetX = { -500 },
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = FastOutSlowInEasing
                    )
                )
            }) {
            StartPage(
                modifier = modifier,
                navController = navController,
                authViewModel = authViewModel
            )
        }

        composable(route = "login",
            enterTransition = {
                slideInHorizontally(
                    initialOffsetX = { it }, // it == fullWidth
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = FastOutSlowInEasing
                    )
                )
            },
            exitTransition = {
                slideOutHorizontally(
                    targetOffsetX = { it },
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = FastOutSlowInEasing
                    )
                )
            }

        ) {
                LoginPage(
                    modifier = Modifier.fillMaxSize(),
                    navController = navController,
                    authViewModel = authViewModel
                )
        }

        composable("signup") {
            SignupPage(
                modifier = modifier,
                navController = navController,
                authViewModel = authViewModel
            )
        }

        composable("home") {
            HomePage(
                modifier = modifier,
                navController = navController,
                authViewModel = authViewModel
            )
        }
    }
}

修复方案

问题核心是当前StartScreen的退出动画未完全滑出屏幕,且未配置返回导航时的对应动画。调整动画参数并补充双向导航的动画逻辑即可解决:

@Composable
fun MyAppNavigation(
    modifier: Modifier, authViewModel: AuthViewModel
) {
    val navController = rememberNavController()
    NavHost(navController = navController, startDestination = "start") {
        composable(
            route = "start",
            // 从Login返回Start时:从左侧滑入
            enterTransition = {
                slideInHorizontally(
                    initialOffsetX = { -it },
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = FastOutSlowInEasing
                    )
                )
            },
            // 从Start导航到Login时:向左完全滑出屏幕
            exitTransition = {
                slideOutHorizontally(
                    targetOffsetX = { -it },
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = FastOutSlowInEasing
                    )
                )
            },
            // 返回时Login的退出动画
            popExitTransition = {
                slideOutHorizontally(
                    targetOffsetX = { it },
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = FastOutSlowInEasing
                    )
                )
            }
        ) {
            StartPage(
                modifier = modifier,
                navController = navController,
                authViewModel = authViewModel
            )
        }

        composable(
            route = "login",
            // 从Start导航到Login时:从右侧滑入
            enterTransition = {
                slideInHorizontally(
                    initialOffsetX = { it },
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = FastOutSlowInEasing
                    )
                )
            },
            // 从Login导航到其他页面时:向右滑出
            exitTransition = {
                slideOutHorizontally(
                    targetOffsetX = { it },
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = FastOutSlowInEasing
                    )
                )
            },
            // 返回时Start的进入动画
            popEnterTransition = {
                slideInHorizontally(
                    initialOffsetX = { -it },
                    animationSpec = tween(
                        durationMillis = 1000,
                        easing = FastOutSlowInEasing
                    )
                )
            }
        ) {
            LoginPage(
                modifier = Modifier.fillMaxSize(),
                navController = navController,
                authViewModel = authViewModel
            )
        }

        composable("signup") {
            SignupPage(
                modifier = modifier,
                navController = navController,
                authViewModel = authViewModel
            )
        }

        composable("home") {
            HomePage(
                modifier = modifier,
                navController = navController,
                authViewModel = authViewModel
            )
        }
    }
}

关键修改点

  • StartScreen退出动画:将targetOffsetX从固定值-500改为{ -it },让页面完全滑出屏幕左侧,避免覆盖LoginScreen。
  • 补充返回动画配置:通过popEnterTransition和popExitTransition定义返回导航时的动画逻辑,保证双向导航都有流畅过渡。
  • 对齐动画方向:导航到Login时,Start左滑退出、Login右滑进入;返回时,Login右滑退出、Start左滑进入,完全匹配目标效果。

内容的提问来源于stack exchange,提问作者Fatima Jamal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:47:07