Jetpack Compose无限动画中Float转DP实现Card Elevation失效问题
问题:Jetpack Compose中Card的elevation动画不生效
- 动画值用于
Modifier.shadow()时正常工作,但用于Card的elevation属性时完全无法启动 - 怀疑问题出在Float转DP的转换上,尝试多种方案未解决
原代码:
@Composable fun Greeting(modifier: Modifier = Modifier) { Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally , verticalArrangement = Arrangement.Center ){ val infiniteTransition = rememberInfiniteTransition(label = "") val value by infiniteTransition.animateFloat( initialValue = 20f, targetValue = 200f, animationSpec = infiniteRepeatable( animation = tween( durationMillis = 400, ), repeatMode = RepeatMode.Reverse ), label = "" ) // Convert the floating-point value to a dimension value val elevationValue = with(LocalDensity.current) { value.dp } Card( modifier = Modifier.padding(30.dp) //.shadow(elevationValue) , elevation = CardDefaults.cardElevation(elevationValue) , shape = RectangleShape, ){ Text( text = "Infinite Animation ", fontSize = 30.sp, textAlign = TextAlign.Center, modifier = Modifier.padding(10.dp) ) } } }
解决方案
核心问题是手动将Float转Dp的方式无法让Card正确感知动画状态变化,改用animateDp直接生成Dp类型的动画值即可解决:
- 使用
rememberInfiniteTransition的animateDp方法,直接定义Dp范围的动画,无需手动转换 - 将动画生成的Dp值直接传入
CardDefaults.cardElevation()
修改后的代码:
@Composable fun Greeting(modifier: Modifier = Modifier) { Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { val infiniteTransition = rememberInfiniteTransition(label = "") // 直接使用animateDp生成Dp类型的动画值 val elevationValue by infiniteTransition.animateDp( initialValue = 20.dp, targetValue = 200.dp, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 400), repeatMode = RepeatMode.Reverse ), label = "" ) Card( modifier = Modifier.padding(30.dp), elevation = CardDefaults.cardElevation(elevationValue), shape = RectangleShape, ) { Text( text = "Infinite Animation ", fontSize = 30.sp, textAlign = TextAlign.Center, modifier = Modifier.padding(10.dp) ) } } }
原理说明
Modifier.shadow()可以直接接收动态变化的Dp值,因为它是Modifier的一部分,会随重组实时更新Card的elevation参数依赖CardElevation配置,使用animateDp生成的状态值时,Compose能正确跟踪状态变化并触发Card的elevation动画,而手动转换的Dp值无法被正确识别为可动画状态
内容的提问来源于stack exchange,提问作者Maham
相关产品推荐
相关产品推荐

