如何在Jetpack Compose中实现前后对比动画效果?

我曾使用weight属性或通过无限动画修改宽度,但无法实现上图gif所示的效果,请问如何在Jetpack Compose中实现该效果?
解决方案
你可以通过状态驱动的animateFloatAsState结合布局比例控制,配合循环任务实现GIF中的连贯宽度动画效果,以下是两种常见场景的实现:
场景1:多元素依次伸缩动画(匹配多数同类加载波纹效果)
@Composable fun SequentialWidthWaveAnimation() { // 控制当前动画作用的元素索引 var activeIndex by remember { mutableStateOf(0) } // 当前元素的宽度比例,在基础值和扩展值间过渡 val targetFraction = if (activeIndex % 2 == 0) 0.7f else 0.3f val widthFraction by animateFloatAsState( targetValue = targetFraction, animationSpec = tween(500) ) // 启动无限循环的动画切换任务 LaunchedEffect(Unit) { while (true) { delay(500) activeIndex = (activeIndex + 1) % 4 // 4为元素总数,按需调整 } } Row( modifier = Modifier.fillMaxWidth().padding(16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp) ) { repeat(4) { index -> Box( modifier = Modifier .fillMaxWidth(if (index == activeIndex / 2) widthFraction else 0.3f) .height(40.dp) .background(Color(0xFF2196F3)) ) } } }
场景2:单个元素波浪式宽度变化
如果GIF是单个元素的宽度往复波动,可使用repeatable动画搭配关键帧:
@Composable fun SingleElementWidthWave() { val widthFraction by animateFloatAsState( targetValue = 1f, animationSpec = repeatable( iterations = AnimationConstants.Infinite, animation = keyframes { durationMillis = 1400 // 匹配GIF动画时长 0.4f at 0 0.9f at 500 0.4f at 900 0.9f at 1400 } ) ) Box( modifier = Modifier .fillMaxWidth(widthFraction) .height(40.dp) .background(Color(0xFF2196F3)) .padding(horizontal = 16.dp) ) }
核心要点:
- 避免直接修改固定宽度值,用
fillMaxWidth(fraction)配合动画状态,适配不同屏幕尺寸 - 多元素动画通过
LaunchedEffect控制状态切换顺序,保证动画连贯性 - 调整
tween/keyframes的时长参数,匹配GIF中的动画速度
内容的提问来源于stack exchange,提问作者Abdullah
相关产品推荐
相关产品推荐

