如何防止LazyColumn滚动时Lottie动画因重组重新播放?
解决LazyColumn滚动时Lottie动画重置的问题
当LazyColumn滚动时,Compose会按需重组可见项,若未正确配置项的标识或动画状态,Lottie动画会因重组重启。以下是具体解决方案:
1. 为LazyColumn的项添加稳定Key
在items方法中传入唯一且稳定的key,确保每个Loader实例的身份固定,避免Compose因滚动复用或重建组件:
LazyColumn( modifier = Modifier.fillMaxHeight(), verticalArrangement = Arrangement.Center ) { items(3, key = { it }) { // 使用索引作为唯一Key(有业务ID时更推荐用业务ID) Loader() } }
2. 锁定Loader的动画状态
调整animateLottieCompositionAsState的参数,禁止重组时重启动画,并保留播放进度:
@Composable fun Loader() { val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.water_loading)) val progressAsState by animateLottieCompositionAsState( composition = composition, clipSpec = LottieClipSpec.Progress(0f, 1f), repeatMode = LottieConstants.RepeatMode.RESTART, iterations = LottieConstants.IterateForever, // 关键参数:禁止重组时自动重启动画 restartOnPlay = false ) LottieAnimation( composition = composition, progress = { progressAsState }, modifier = Modifier.requiredHeight(350.dp), contentScale = ContentScale.FillHeight ) }
如果需要更精细的控制,可以手动使用LottieAnimatable结合LaunchedEffect管理动画状态,确保进度在重组时不丢失:
@Composable fun Loader() { val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.water_loading)) val animatable = remember { LottieAnimatable() } val progress = remember { mutableStateOf(0f) } LaunchedEffect(composition) { composition ?: return@LaunchedEffect animatable.animate( composition = composition, clipSpec = LottieClipSpec.Progress(0f, 1f), repeatMode = LottieConstants.RepeatMode.RESTART, iterations = LottieConstants.IterateForever ) { progress.value = this.progress } } LottieAnimation( composition = composition, progress = { progress.value }, modifier = Modifier.requiredHeight(350.dp), contentScale = ContentScale.FillHeight ) }
3. 避免无意义的上游重组
确保Container中的状态(比如items)已用remember稳定保存,避免因上游无意义重组触发LazyColumn的不必要刷新。
完成以上修改后,滚动LazyColumn时,Lottie动画会持续播放,不会因重组从头开始。
内容的提问来源于stack exchange,提问作者MSG999
相关产品推荐
相关产品推荐

