如何在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
相关产品推荐
相关产品推荐

