如何在Jetpack Compose中每次从头播放Lottie动画
解决Compose中Lottie动画切换时从头播放的问题
你的问题核心是动画切换时进度状态未重置,导致新动画直接沿用旧进度值(比如前一个动画播放完毕后的1F),或是固定进度到0F后无法触发播放逻辑。以下是具体解决思路和代码实现:
关键问题分析
rememberLottieComposition默认会缓存composition实例,若未指定依赖key,动画资源更换时不会重新加载新资源的状态。animateLottieCompositionAsState的进度状态会保留之前的数值,新动画加载后直接跳到该进度,导致显示静态帧。- 直接固定
progress = {0F}只会停在第一帧,缺少驱动动画播放的状态逻辑。
解决方案
1. 让Composition随资源变化重新加载
给rememberLottieComposition添加与动画资源绑定的key,确保资源更换时丢弃旧的composition并加载新实例。
2. 重置播放进度状态
给animateLottieCompositionAsState添加composition作为key,同时开启restartOnPlay,确保新动画加载后进度状态重置。
3. 强制触发从头播放
用LaunchedEffect监听composition的变化,当新资源加载完成后,通过切换播放状态强制动画从头开始。
完整代码示例
// 控制当前显示动画的状态,切换该值即可更换动画 val currentAnimationRes by remember { mutableStateOf(R.raw.first_animation) } // 绑定资源ID作为key,资源变化时重新加载Composition val composition by rememberLottieComposition( spec = LottieCompositionSpec.RawRes(currentAnimationRes), key = currentAnimationRes ) // 控制播放状态,用Composition作为key,确保新资源加载后重置进度 val isPlaying = remember { mutableStateOf(true) } val progress by animateLottieCompositionAsState( composition = composition, isPlaying = isPlaying.value, restartOnPlay = true, key = composition ) // 监听Composition变化,强制触发从头播放 LaunchedEffect(composition) { composition ?: return@LaunchedEffect // 先暂停再播放,确保进度重置到0 isPlaying.value = false delay(10) isPlaying.value = true } LottieAnimation( composition = composition, progress = { progress }, modifier = modifier )
代码说明
key = currentAnimationRes:确保每次动画资源ID变化时,重新加载对应的Lottie文件,避免复用旧资源的缓存状态。key = composition:当新的composition加载完成后,animateLottieCompositionAsState的内部状态会重置,配合restartOnPlay = true,播放时直接从0进度开始。LaunchedEffect(composition):监听composition的创建,通过短暂切换播放状态,强制触发动画的从头播放,解决可能存在的进度残留问题。
内容的提问来源于stack exchange,提问作者Alejandro Casanova
相关产品推荐
相关产品推荐

