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

Android Compose中InfiniteTransition无限动画重启触发动作的实现方案

在Android Compose中监听InfiniteTransition动画重启的方案

你当前用InfiniteTransition实现的无限keyframes动画运行正常,但要监听每次动画重启的触发点,确实没有直接的onComplete回调可用。下面提供两种可行的实现方案:

方案一:手动控制动画循环(推荐)

放弃InfiniteTransition,改用LaunchedEffect配合animate函数手动管理动画周期,这样可以在每次动画完成(即重启前)精准触发动作:

var x by remember { mutableFloatStateOf(0.5f) }
val cycleTime = 2000 // 你的动画周期时长

LaunchedEffect(Unit) {
    while (true) {
        // 执行单次keyframes动画
        animate(
            initialValue = 0.5f,
            targetValue = 0.5f, // keyframes最后回到初始值,这里仅作为占位
            animationSpec = keyframes {
                durationMillis = cycleTime
                0.5f at 0 with xEasingOut
                1.0f at cycleTime / 4 with xEasingBack
                0.5f at cycleTime / 2 with xEasingOut
                0.0f at cycleTime * 3/4 with xEasingBack
                0.5f at cycleTime with xEasingOut
            }
        ) { value, _ ->
            x = value
        }
        // 动画完成,触发你需要的动作
        // 这里就是每次动画重启前的执行点
        // do something...
    }
}

这种方式完全规避了浮点精度问题,触发时机精准,而且逻辑直观,容易维护。

方案二:监听动画值的周期节点

如果不想改动现有InfiniteTransition的代码,可以用SnapshotFlow监听动画值,结合区间判断来捕获周期结束的节点:

val infiniteTransition = rememberInfiniteTransition(label = "")
val x by infiniteTransition.animateFloat(
    initialValue = 0.5f,
    targetValue = 0.0f,
    animationSpec = infiniteRepeatable(
        animation = keyframes {
            durationMillis = cycleTime
            0.5f at 0 with xEasingOut
            1.0f at cycleTime / 4 with xEasingBack
            0.5f at cycleTime / 2 with xEasingOut
            0.0f at cycleTime * 3/4 with xEasingBack
            0.5f at cycleTime with xEasingOut
        },
        repeatMode = RepeatMode.Restart,
    ),
    label = "x animation"
)

LaunchedEffect(x) {
    SnapshotFlow { x }
        .distinctUntilChanged()
        // 用区间判断替代精确等于,避免浮点精度问题
        .filter { it in 0.49f..0.51f }
        .drop(1) // 跳过初始加载时的0.5f值
        .collect {
            // 触发动作
            // do something...
        }
}

注意:这种方式依赖动画值回到初始区间,需要根据你的动画参数调整区间范围,避免误触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:03:21