Compose中如何实现补间动画时长的动态调整?
Compose无限重复动画时长不更新的问题解决
问题原因
使用animateIntOffsetAsState配合infiniteRepeatable时,若动画的目标值未发生变化,即使修改animationSpec中的durationMillis参数,Compose不会自动重启动画——因为它判定当前动画仍在运行且目标状态未改变,无需重新生成动画实例。
解决方法
给animateIntOffsetAsState添加key参数,将animTime和easing作为依赖项。当这些值变化时,Compose会重新创建动画,从而应用新的时长配置。
修改后的代码
@Composable fun test() { var animTime by remember { mutableIntStateOf(3000) } var easing by remember { mutableStateOf(FastOutSlowInEasing) } var containerSize by remember { mutableStateOf(IntSize.Zero) } val boxSize = 100.dp // 修正DP转像素的正确方式 val moveX = max(0, containerSize.width - boxSize.toPx().toInt()) val moveOffset by animateIntOffsetAsState( targetValue = IntOffset(moveX, 0), animationSpec = infiniteRepeatable( tween( durationMillis = animTime, easing = easing, ) ), // 依赖animTime和easing,值变化时重启动画 key = animTime to easing ) Row(modifier = Modifier.fillMaxWidth()) { Column( modifier = Modifier.weight(1f) .background(Color.Red) .onSizeChanged { containerSize = it } ) { Box( modifier = Modifier.size(boxSize) .offset { moveOffset } .background(Color.Cyan) ) } Column(Modifier.weight(1f)) { Button(onClick = { animTime = if (animTime == 3000) animTime / 10 else animTime * 10 }) { Text("dur=$animTime") } } } }
额外说明
你代码中注释的Offset must come before background (why?):Compose的Modifier是按顺序执行的,offset仅改变元素的绘制位置(布局位置不变)。如果background在offset之前应用,背景会绘制在原始布局位置,而偏移后的Box会在新位置显示,导致背景与Box分离。因此需要先应用offset再应用background,让背景跟随Box的偏移位置。
内容的提问来源于stack exchange,提问作者Some Noob Student
相关产品推荐
相关产品推荐

