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

Jetpack Compose中如何正确启停文本旋转动画

Jetpack Compose 旋转动画启停的正确实现方法

你当前的问题核心是用animateFloatAsState配合infiniteRepeatable动画时,没法直接中断动画流程。当isRotating设为false后,动画会自动触发从当前角度到0°的平滑过渡,而不是立即停止,这就导致了反向旋转、循环异常的问题。

改用Animatable就能解决这个问题,它支持手动控制动画的启停,还能直接保留当前状态。修改后的代码如下:

@Composable
fun RotatingText() {
    val angle = remember { Animatable(0f) }
    var isRotating by remember { mutableStateOf(false) }
    val coroutineScope = rememberCoroutineScope()

    Box(
        modifier = Modifier
            .graphicsLayer { rotationZ = angle.value }
            .clickable {
                if (!isRotating) {
                    isRotating = true
                    // 启动无限旋转动画
                    coroutineScope.launch {
                        angle.animateTo(
                            targetValue = 360f,
                            animationSpec = infiniteRepeatable(
                                animation = tween(2000, easing = LinearEasing),
                                repeatMode = RepeatMode.Restart
                            )
                        )
                    }
                    // 执行耗时任务,完成后停止动画
                    coroutineScope.launch {
                        doSlowProcess()
                        isRotating = false
                        // 立即停止动画,保持当前旋转角度
                        angle.stop()
                        // 如果需要停止后立即回到0°,替换成下面这句:
                        // angle.snapTo(0f)
                    }
                }
            }
    ) {
        Text("START")
    }
}

// 模拟耗时任务
suspend fun doSlowProcess() {
    delay(5000)
}

关键说明:

  • Animatable的stop()方法会直接终止动画,当前的旋转角度会被保留,不会触发反向过渡逻辑。
  • 分开启动动画协程和耗时任务协程,确保动画能持续运行直到耗时任务完成后被主动停止。
  • 加入isRotating状态判断,避免重复点击导致多个动画协程同时运行,引发混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 06:05:14