如何在Compose Navigation中使用Transition为界面添加圆角与遮罩效果?
你肯定注意到了,Android原生Activity之间跳转时,页面会自动适配设备的圆角显示,退出的Activity还会有一层逐渐变暗的遮罩——这些都是系统默认帮咱们搞定的过渡效果。
但如果用Compose Navigation来构建页面就不一样了:因为这里的页面切换本质上是同一个Activity内部的组件切换,不是真正的Activity跳转,所以系统自带的那些过渡动画根本触发不了。这时候就得咱们自己动手实现圆角和遮罩效果啦。
不过这里有个小限制:Compose自带的Transition组件目前只支持像**淡入淡出(fade)**这类基础动画类型,要实现圆角裁剪和遮罩变暗的效果,得做些定制开发:
实现思路拆解
- 圆角裁剪:给每个页面的根布局外层套一个
Clip组件,把裁剪形状设为RoundedCornerShape(如果要适配设备原生圆角,可以通过LocalContext获取系统配置的圆角值)。在页面切换过程中保持这个裁剪效果,确保页面内容不会超出圆角范围。 - 遮罩变暗效果:在退出页面的上层添加一个半透明的黑色
Box,用Transition来控制它的透明度从0平滑过渡到0.5左右,模拟系统那种逐渐变暗的遮罩。
简单代码示例
比如我们给导航跳转时添加自定义过渡:
// 定义退出页面的自定义过渡动画 fun customExitTransition(): Transition { return slideOutHorizontally( targetOffsetX = { -it / 2 }, animationSpec = tween(300) ) + fadeOut(animationSpec = tween(300)) + remember { // 保持页面圆角裁剪的过渡 Transition { val shape by animateValue( initialValue = RoundedCornerShape(16.dp), targetValue = RoundedCornerShape(16.dp), typeConverter = CornerShape.VectorConverter ) Modifier.clip(shape) } } } // 导航跳转时应用自定义过渡 navController.navigate("detail_screen") { exitTransition = customExitTransition() enterTransition = slideInHorizontally( initialOffsetX = { it / 2 }, animationSpec = tween(300) ) + fadeIn(animationSpec = tween(300)) } // 在退出页面中添加遮罩动画 val transitionState = rememberTransitionState() val maskAlpha by transitionState.animateFloat( transitionSpec = { tween(300) } ) { state -> if (state is NavTransitionState.Exit) 0.5f else 0f } if (transitionState is NavTransitionState.Exit) { Box( modifier = Modifier .fillMaxSize() .background(Color.Black.copy(alpha = maskAlpha)) ) }
这样就能模拟出和原生Activity跳转类似的圆角+遮罩过渡效果啦。
备注:内容来源于stack exchange,提问作者dude really
相关产品推荐
相关产品推荐

