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

如何在Jetpack Compose中实现Material Motion容器转场动画

在Jetpack Compose中实现类似Material Motion的容器转场动画

当然有,Jetpack Compose官方提供了Compose Material Motion库,专门用来实现类似传统View系统中Material Motion的转场效果,包括你需要的容器转场(Container Transform),完美适配Navigation Component与Composable页面跳转场景。

下面是具体的实现步骤和代码示例:

1. 添加依赖

首先确保项目中引入匹配Compose核心版本的稳定版Material Motion库,同时保证Navigation Compose依赖已存在:

dependencies {
    implementation "androidx.compose.material:material-motion:1.6.1"
    implementation "androidx.navigation:navigation-compose:2.7.7"
}

2. 标记共享转场元素

在FirstPage的FloatingActionButton上,用Modifier.sharedElement()标记转场源元素,指定唯一标识key:

@Composable
fun FirstPage(navController: NavController) {
    Scaffold(
        floatingActionButton = {
            FloatingActionButton(
                onClick = { navController.navigate("second_page") },
                modifier = Modifier
                    .sharedElement(
                        key = "fab_transition",
                        state = rememberSharedContentState()
                    )
            ) {
                Icon(Icons.Default.Add, contentDescription = "进入第二页")
            }
        }
    ) { innerPadding ->
        Text("第一页", modifier = Modifier.padding(innerPadding))
    }
}

在SecondPage中,选择要和FAB做转场的目标容器(比如页面卡片),同样用Modifier.sharedElement()标记,key必须和源元素完全一致:

@Composable
fun SecondPage(navController: NavController) {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("第二页") },
                navigationIcon = {
                    IconButton(onClick = { navController.popBackStack() }) {
                        Icon(Icons.Default.ArrowBack, contentDescription = "返回")
                    }
                }
            )
        }
    ) { innerPadding ->
        Card(
            modifier = Modifier
                .fillMaxSize()
                .padding(innerPadding)
                .sharedElement(
                    key = "fab_transition",
                    state = rememberSharedContentState()
                ),
            shape = RoundedCornerShape(16.dp)
        ) {
            Text("第二页内容", modifier = Modifier.align(Alignment.Center))
        }
    }
}

3. 配置Navigation的转场动画

在NavHost中,为second_page的Composable配置enterTransition和exitTransition,使用containerTransform实现容器转场效果:

@Composable
fun AppNavHost(navController: NavHostController) {
    NavHost(
        navController = navController,
        startDestination = "first_page"
    ) {
        composable("first_page") {
            FirstPage(navController)
        }
        composable(
            route = "second_page",
            enterTransition = {
                containerTransform(
                    initialState = initialState,
                    targetState = targetState,
                    sizeTransform = SizeTransform(clip = false)
                )
            },
            exitTransition = {
                containerTransform(
                    initialState = initialState,
                    targetState = targetState,
                    sizeTransform = SizeTransform(clip = false)
                )
            }
        ) {
            SecondPage(navController)
        }
    }
}

关键细节说明

  • sharedElement的key是转场元素关联的核心,必须在源、目标元素间保持唯一且一致
  • containerTransform会自动处理元素的大小、形状、位置过渡,完全匹配你需要的示意图效果
  • 可通过调整containerTransform的fadeMode、durationMillis等参数,自定义动画的淡出模式、时长等细节

内容的提问来源于stack exchange,提问作者Sergey Grishin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 08:03:22