Jetpack Compose平滑启停旋转动画:解决停止跳变问题
解决方案
要实现停止时保留当前角度、下次启动从该角度继续的平滑旋转动画,不要用InfiniteTransition(它无法暂停并保留状态),改用Animatable手动控制动画生命周期,结合协程实现无限旋转,具体实现如下:
核心思路
- 用
Animatable存储当前旋转角度,它能自动保留当前值,支持暂停/继续操作 - 用
remember保存上次停止时的角度,确保重启动画时从该位置启动 - 通过
LaunchedEffect监听isFetchingNewRates状态,动态启动或取消旋转协程
完整代码实现
@Composable fun RatesStatus( ratesStatus: RateStatus, onRateRefreshClicked: () -> Unit, isFetchingNewRates: Boolean = false ) { // 保存上次停止时的旋转角度 var lastRotation by remember { mutableStateOf(0f) } // 初始化Animatable,初始值为上次停止的角度 val rotation = remember { Animatable(lastRotation) } LaunchedEffect(isFetchingNewRates) { if (isFetchingNewRates) { // 启动时快速定位到上次停止的角度 rotation.snapTo(lastRotation) // 无限循环旋转:每次累加360度,线性动画持续2秒 while (true) { rotation.animateTo( targetValue = rotation.value - 360f, animationSpec = tween(durationMillis = 2000, easing = LinearEasing) ) } } else { // 停止动画时,保存当前角度到lastRotation lastRotation = rotation.value // 取消当前动画协程 rotation.stop() } } Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { Row { Image( modifier = Modifier.size(50.dp), painter = painterResource(Res.drawable.exchange_illustration), contentDescription = "Exchange rate illustration" ) Spacer(modifier = Modifier.width(12.dp)) Column { Text( text = displayCurrentDateTime(), color = Color.White ) Text( text = stringResource(ratesStatus.title), color = ratesStatus.color, fontSize = MaterialTheme.typography.bodySmall.fontSize ) } } IconButton( onClick = onRateRefreshClicked ) { Icon( modifier = Modifier .size(24.dp) .graphicsLayer { // 直接使用Animatable的当前值作为旋转角度 rotationZ = rotation.value }, painter = painterResource(Res.drawable.refresh_ic), contentDescription = stringResource(Res.string.start_refresh), tint = staleColor ) } } }
关键细节说明
Animatable状态保留:Animatable内部维护当前动画值,停止时不会自动重置,彻底解决停止时跳转初始角度的问题lastRotation的作用:组件重组时,Animatable会重新初始化,lastRotation确保重启动画时从上次停止的位置继续- 协程循环控制:
while(true)配合animateTo实现无限旋转,每次旋转完成后自动累加角度,保证动画连续性 - 平滑启停:启动时用
snapTo快速定位到上次停止角度,无跳转;停止时直接保存当前值,动画自然终止
内容的提问来源于stack exchange,提问作者ant2009
相关产品推荐
相关产品推荐

