You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose实现盒子依次延迟1秒动画时delay.value不更新问题

问题根源

  • 所有Box共用了同一个动画实例和Modifier,天然不可能出现先后动画的效果
  • 动画初始化时已经读取了初始的delay.value=0,后续循环中修改delay.value的时候,已经创建好的动画不会响应这个更新,而且你在组合阶段直接修改MutableState的值还会触发不必要的重组,甚至可能导致无限循环
  • 你定义的delay状态完全没必要,每个盒子的延迟可以直接通过遍历的index计算得到

修正后代码

@Composable
fun Rocket(
    isRocketEnabled: Boolean,
    maxWidth: Dp,
    maxHeight: Dp
) {
    val tileSize = 50.dp
    // 颜色列表用remember包裹避免重复创建
    val colorList = remember {
        listOf(
            Color(0xffDFFF00),
            Color(0xffFFBF00),
            Color(0xffFF7F50),
            Color(0xffDE3163),
            Color(0xff9FE2BF),
            Color(0xff40E0D0),
            Color(0xff6495ED),
            Color(0xffCCCCFF),
        )
    }

    // 每个颜色对应独立的Box和动画逻辑
    colorList.forEachIndexed { index, color ->
        val modifier = if (!isRocketEnabled) {
            Modifier.offset(y = maxHeight - tileSize)
        } else {
            // 每个Box单独创建动画实例
            val infiniteTransition = rememberInfiniteTransition(label = "rocket_$index")
            val positionState = infiniteTransition.animateFloat(
                initialValue = 0f,
                targetValue = 1f,
                animationSpec = infiniteRepeatable(
                    animation = tween(
                        durationMillis = 2000,
                        // 直接用index计算延迟,不需要额外状态存储
                        delayMillis = index * 1000,
                        easing = LinearEasing
                    )
                ), label = "position_$index"
            )
            Modifier.offset(
                x = (maxWidth - tileSize) * positionState.value,
                y = (maxHeight - tileSize) - (maxHeight - tileSize) * positionState.value,
            )
        }

        Box(
            modifier = modifier
                .width(tileSize)
                .height(tileSize)
                .background(color = color)
        )
    }
}

修正说明

  1. 把颜色列表的遍历放到最外层,每个颜色对应一个独立的Box,每个Box单独创建自己的动画实例
  2. 去掉冗余的delay状态,直接用遍历的index计算每个动画的延迟时间,第n个盒子延迟n*1000毫秒启动
  3. 每个盒子使用独立的Modifier和动画状态,互不干扰,即可实现依次间隔1秒启动的效果
  4. 对颜色列表做了remember缓存,避免每次重组都创建新的列表,优化性能

内容的提问来源于stack exchange,提问作者Code Poet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 01:15:04