Jetpack Compose中如何实现Column尺寸缩至0.dp的动画效果
问题描述
希望在所有动画完成后将Column的尺寸设置为0.dp,即子元素全部隐藏后让Column收缩至0.dp。尝试的代码运行后,动画完成仍有残留空间,使用animateSizeAsState时出现类型不匹配错误:
Type mismatch. Required: Size Found: { Comparable & Number }
解决方案
1. 修复animateSizeAsState类型不匹配问题
animateSizeAsState的targetValue参数要求是Size类型,而非单纯数值。需要将目标尺寸封装为Size对象:
- 显示状态:用
onGloballyPositioned获取的Column实际尺寸创建Size - 隐藏状态:直接使用
Size(0f, 0f)
2. 同步子元素动画与Column尺寸动画
将所有动画的时长保持一致,确保子元素消失动画和Column收缩动画同步。也可以让子元素随Column收缩自然隐藏,简化实现逻辑。
修改后的完整代码
@Preview(showBackground = true) @Composable fun MoveText() { var columnSize by remember { mutableStateOf(Size.Zero) } var visible by remember { mutableStateOf(true) } // Column尺寸收缩动画 val animatedSize by animateSizeAsState( targetValue = if (visible) columnSize else Size.Zero, animationSpec = tween(durationMillis = 1000) ) ScrollComposeTheme { Column( modifier = Modifier .fillMaxWidth() .padding(start = 16.dp, top = 16.dp) ) { Column( modifier = Modifier .onGloballyPositioned { coordinates -> // 记录Column初始像素尺寸 columnSize = Size( width = coordinates.size.width.toFloat(), height = coordinates.size.height.toFloat() ) } .size(animatedSize.width.dp, animatedSize.height.dp) .background(Color.LightGray) ) { Image( modifier = Modifier.padding(top = 13.dp), alpha = if (visible) 1f else 0f, imageVector = Icons.Default.ShoppingCart, contentDescription = null, ) Text( modifier = Modifier.padding(top = 6.dp), text = "Hello, Anna", fontSize = 20.sp, color = Color.Black.copy(alpha = if (visible) 1f else 0f), ) } Button( modifier = Modifier.padding(top = 10.dp), onClick = { visible = !visible } ) { Text(text = "Move Text") } } } }
额外优化建议
- 如果需要子元素偏移动画和Column收缩更贴合,可以根据动画尺寸的比例计算偏移量:
val offsetRatio = if (columnSize.height == 0f) 1f else animatedSize.height / columnSize.height val iconOffset = 13.dp * offsetRatio - 更简洁的实现方式:使用
animateContentSize,自动根据内容显示/隐藏触发尺寸收缩动画:Column( modifier = Modifier .animateContentSize(tween(1000)) .background(Color.LightGray) ) { if (visible) { Image(modifier = Modifier.padding(top = 13.dp), imageVector = Icons.Default.ShoppingCart, contentDescription = null) Text(modifier = Modifier.padding(top = 6.dp), text = "Hello, Anna", fontSize = 20.sp) } }
内容的提问来源于stack exchange,提问作者Compose Learner
相关产品推荐
相关产品推荐

