前言
在 Jetpack Compose 中实现多帧动画(即逐帧动画,类似 GIF 的效果),主要有以下几种方式:
| 方法 | 适用场景 | 备注 |
|---|---|---|
mutableStateOf + LaunchedEffect |
任意多帧 PNG/JPG 资源 | 最灵活、最常用 |
AnimatedImageVector |
Animated Vector Drawable | 仅限矢量动画 |
AndroidView + AnimationDrawable |
兼容旧逻辑 | 不推荐用于新项目 |
Lottie |
复杂动画 |
使用Animatable + LaunchedEffect
手动控制帧切换
Jetpack Compose 本身没有直接提供“逐帧动画”的内置组件,但你可以通过组合 remember、mutableStateOf、LaunchedEffect 和协程来实现。
示例代码
1 |
|
注意💡:
你需要提前将所有帧作为 drawable 资源放入项目中。
优化建议
- 预加载图片:避免在每一帧都调用
painterResource(它内部有缓存,但最好确保资源已加载)。 - 控制生命周期:通过
isPlaying参数控制动画启停,避免内存泄漏。 - 使用
rememberUpdatedState:如果frameIds或durationPerFrame可能变化,需用rememberUpdatedState包裹以避免重启协程。
使用AnimatedImageVector
仅适用于 VectorDrawable 动画
Animated Vector Drawable 是一种基于 XML 的 Android 原生动效格式,结合了矢量图形与属性动画,适合实现轻量、流畅、可缩放的图标动画。
示例代码
如果你的动画是 Animated Vector Drawable(AVD),可以使用:
1 | val image = AnimatedImageVector.animatedVectorResource(R.drawable.animated_vector) |
但这只适用于 Android 原生支持的 AnimatedVectorDrawable,不适用于普通位图(PNG/JPG)的逐帧动画。
生成工具
使用传统View动画(不推荐)
虽然可以在 Compose 中嵌入 AndroidView 并使用传统 ImageView + AnimationDrawable,但这违背了 Compose 的声明式理念,且性能和状态管理不如纯 Compose 方案。
使用动画库Lottie
在 Jetpack Compose 中使用 Lottie(由 Airbnb 开发的动画库)非常方便,官方提供了对 Compose 的原生支持。
在 Jetpack Compose 中使用 Lottie 只需三步:
- 添加
lottie-compose依赖 - 放入
.json到res/raw - 用
rememberLottieComposition+animateLottieCompositionAsState+LottieAnimation
它比 AVD 更强大,适合复杂动效;而 AVD 更适合轻量、原生图标动画。两者可根据场景搭配使用。
详细使用