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

如何暂停/恢复Jetpack Compose虚线边框的无限过渡动画?

解决Jetpack Compose虚线边框动画切换跳变问题

问题场景

在Android应用中通过自定义Modifier绘制虚线边框,需求是视图选中时播放虚线动画,未选中时暂停动画(保持当前位置)。使用InfiniteTransition实现后,切换动画状态时出现明显跳变(动画状态切换时虚线直接跳回初始位置),需要优化实现方式避免跳变。

问题根源

当前代码在animate为false时直接将dashPathEffect的phase设为0f,导致动画状态切换时,虚线偏移量从当前动画值突然跳转到0,产生视觉跳变。且InfiniteTransition没有直接的暂停API,无法直接暂停动画并保留当前进度。

解决方案

放弃InfiniteTransition,改用手动维护偏移量状态结合协程的方式控制动画:

  • 用状态变量保存当前的虚线偏移值
  • 当animate为true时,通过LaunchedEffect启动协程,持续更新偏移量实现无限动画
  • 当animate为false时,停止协程,保留当前偏移量,避免跳变

优化后完整代码

fun Modifier.dashedBorder(
    color: Color,
    strokeWidth: Dp,
    strokeLength: Dp,
    animate: Boolean = false,
) = composed(
    factory = {
        val density = LocalDensity.current
        val strokeWidthPx = density.run { strokeWidth.toPx() }
        val strokeLengthPx = density.run { strokeLength.toPx() }
        val dashCycleLength = strokeLengthPx * 2 // 虚线+间隔的总长度

        // 保存当前虚线偏移量的状态
        val currentOffset = remember { mutableStateOf(0f) }

        LaunchedEffect(animate) {
            if (animate) {
                // 动画播放时,持续更新偏移量
                while (true) {
                    // 计算下一帧的偏移值,循环回到0
                    currentOffset.value = (currentOffset.value + 2f) % dashCycleLength
                    delay(16) // 近似60fps的帧间隔
                }
            }
            // animate为false时,协程自动取消,停止更新偏移量
        }

        this.then(
            Modifier.drawWithCache {
                onDrawBehind {
                    val stroke = Stroke(
                        width = strokeWidthPx,
                        pathEffect = PathEffect.dashPathEffect(
                            intervals = floatArrayOf(strokeLengthPx, strokeLengthPx),
                            phase = currentOffset.value // 始终使用当前偏移量,无跳变
                        )
                    )

                    drawRect(
                        color = color,
                        style = stroke,
                    )
                }
            }
        )
    }
)

补充说明

  • 协程中delay(16)模拟60fps动画帧率,可通过调整步长(+2f)和延迟时间控制动画速度
  • 切换到非动画状态时,协程自动取消,currentOffset保留最后偏移值,虚线停在当前位置无跳变
  • 偏移量超过dashCycleLength后重置为0,实现无限循环的滚动效果

内容的提问来源于stack exchange,提问作者m.reiter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 04:50:18