Android中如何实现Lottie动画的无缝切换?
解决Lottie动画切换时的闪烁问题
问题分析
你当前的实现直接通过切换animationRes更换动画,每次切换都会重新加载对应的LottieComposition。由于加载需要时间,这段间隙会导致画面空白,从而出现闪烁现象。要实现无缝过渡,核心是预加载所有需要的动画资源,并通过过渡动画衔接不同状态。
解决方案
下面是优化后的代码,主要做了这几点改进:
- 预加载所有三个Lottie动画的Composition,避免切换时的加载延迟
- 使用
LottieAnimationSwitcher实现平滑过渡,消除闪烁 - 利用动画结束回调自动切回 idle 状态,比固定
delay更适配不同动画时长
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.gestures.detectDragGestures import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.tooling.preview.Preview import com.airbnb.lottie.compose.* import com.lumen.tomo.R // 定义动画类型枚举,方便管理状态 private enum class AnimationType { IDLE, TAP, SWIPE } @Composable fun ChatView() { // 预加载所有需要的Lottie动画资源 val idleComposition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.cat_idle)) val tapComposition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.cat_headshake)) val swipeComposition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.cat_heart)) var currentAnimation by remember { mutableStateOf(AnimationType.IDLE) } LottieAnimationSwitcher( targetState = currentAnimation, // 设置淡入淡出过渡,消除切换时的闪烁 transitionSpec = { fadeIn() with fadeOut() }, modifier = Modifier .fillMaxSize() .pointerInput(Unit) { detectTapGestures(onTap = { currentAnimation = AnimationType.TAP }) detectDragGestures { _, _ -> currentAnimation = AnimationType.SWIPE } } ) { currentState -> val (composition, iterations) = when (currentState) { AnimationType.IDLE -> idleComposition to LottieConstants.IterateForever AnimationType.TAP -> tapComposition to 1 AnimationType.SWIPE -> swipeComposition to 1 } LottieAnimation( composition = composition, iterations = iterations, onAnimationEnd = { // 非idle动画播放结束后,自动切回idle状态 if (currentState != AnimationType.IDLE) { currentAnimation = AnimationType.IDLE } } ) } } @Preview @Composable fun ChatViewPreview() { ChatView() }
额外说明
- 预加载的Composition会被
remember缓存,不会重复加载,确保切换时资源已就绪 LottieAnimationSwitcher会自动处理新旧动画的过渡,这里用淡入淡出可以让切换更自然,你也可以根据需求替换成其他过渡效果(比如滑入滑出)- 使用
onAnimationEnd回调替代固定delay,能准确匹配动画实际时长,避免提前或延迟切回idle状态
内容的提问来源于stack exchange,提问作者Dayem Saeed
相关产品推荐
相关产品推荐

