前言
在 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 更适合轻量、原生图标动画。两者可根据场景搭配使用。
准备 Lottie 动画文件
AE插件下载
LottieFiles 插件(原 Bodymovin)
LottieFiles for Adobe After Effects: Streamline your animation workflow
添加依赖
在你的 build.gradle(Module 级别)中添加 Lottie Compose 依赖:
检查最新版本:https://github.com/airbnb/lottie-android
1 | dependencies { |
💡 截至 2025 年 12 月,最新稳定版通常是
6.x,支持 Compose 1.5+ 和 Android API 21+。
JSON+图片
如果导出的文件是JSON+图片文件夹
导入动画文件
Lottie-Compose 不会自动从网络或任意路径加载图片,必须将图片放在 Android 可访问的资源目录 中。
推荐做法:把JSON+图片文件夹放入 assets/ 目录
在你的 Android 项目中创建或使用 src/main/assets/ 目录。
将整个images/文件夹(或里面的 PNG 文件)复制进去:
1 | 1app/src/main/assets/ |
注意:
JSON 文件也建议放在
assets/中,方便统一管理。
在 Compose 中使用
1 | import androidx.compose.foundation.layout.size |
矢量图动画
导入动画文件
矢量动画导出只有一个JSON文件
将你的 .json 动画文件(由 After Effects + LottieFiles 导出)放入:
1 | app/src/main/res/raw/your_animation.json |
文件名建议全小写,如
loading.json、success_check.json。
在 Compose 中使用
基础用法
基础用法(自动播放、循环)
1 | import androidx.compose.foundation.layout.size |
控制播放行为
控制播放行为(暂停、反向、速度等)
你可以通过 LottieAnimatable 或控制 animateLottieCompositionAsState 的参数来实现高级控制。
示例:点击播放/暂停
1 |
|
常用参数说明
| 参数 | 说明 |
|---|---|
composition |
通过 rememberLottieComposition 加载的动画资源 |
progress |
动画进度(0f ~ 1f),通常由 animateLottieCompositionAsState 提供 |
modifier |
控制大小、点击等 |
enableMergePaths |
是否启用合并路径(某些动画需要设为 true,但会禁用硬件加速) |
dynamicProperties |
动态修改颜色、文本等内容(高级用法) |
高级:动态修改颜色
高级:动态修改颜色(Dynamic Properties)
1 | val dynamicProperties = remember { |
注意:
keyPath需要根据你的 Lottie JSON 结构确定,可用 LottieFiles 预览器 查看图层名。
性能提示
- Lottie 在 Compose 中默认使用 软件渲染,复杂动画可能影响性能。
- 避免在列表(LazyColumn)中频繁创建
rememberLottieComposition,应提升到 ViewModel 或使用derivedStateOf缓存。 - 对于简单图标动画,仍可考虑 AnimatedVectorDrawable(更轻量)。