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
相关产品推荐
相关产品推荐

