Android Jetpack Compose帧动画-Lottie使用

前言

Lottie 是由 Airbnb 开发并开源的一套跨平台动画解决方案,用于在移动应用、Web 和桌面应用中高效渲染高质量的矢量动画

核心特点:

  • 基于 JSON:设计师使用 Adobe After Effects 制作动画,通过 Bodymovin 插件导出为 JSON 文件。
  • 轻量高效:无需视频或大量帧图,用代码解析 JSON 实时渲染,体积小、性能好。
  • 跨平台支持:官方支持 Android、iOS、React Native、Web(Lottie Web)、Flutter 等。
  • 可交互 & 可编程:开发者可以控制播放、暂停、进度、速度、颜色替换等,实现动态交互效果。
  • 自动适配分辨率:基于矢量,完美适配各种屏幕密度,无模糊问题。

使用动画库Lottie

Jetpack Compose 中使用 Lottie(由 Airbnb 开发的动画库)非常方便,官方提供了对 Compose 的原生支持。

在 Jetpack Compose 中使用 Lottie 只需三步:

  1. 添加 lottie-compose 依赖
  2. 放入 .jsonres/raw
  3. rememberLottieComposition + animateLottieCompositionAsState + LottieAnimation

它比 AVD 更强大,适合复杂动效;而 AVD 更适合轻量、原生图标动画。两者可根据场景搭配使用。

准备 Lottie 动画文件

AE插件下载

LottieFiles 插件(原 Bodymovin)

LottieFiles for Adobe After Effects: Streamline your animation workflow

添加依赖

在你的 build.gradle(Module 级别)中添加 Lottie Compose 依赖:

Android - Jetpack Compose

检查最新版本:https://github.com/airbnb/lottie-android

1
2
3
dependencies {
implementation("com.airbnb.android:lottie-compose:6.6.6")
}

版本

💡 截至 2025 年 12 月,最新稳定版通常是 6.x,支持 Compose 1.5+ 和 Android API 21+。

JSON+图片

如果导出的文件是JSON+图片文件夹

导入动画文件

Lottie-Compose 不会自动从网络或任意路径加载图片,必须将图片放在 Android 可访问的资源目录 中。

推荐做法:把JSON+图片文件夹放入 assets/ 目录

在你的 Android 项目中创建或使用 src/main/assets/ 目录。

将整个images/文件夹(或里面的 PNG 文件)复制进去:

1
2
3
4
5
1app/src/main/assets/
2 ├── vs_success.json
3 └── images/
4 ├── img_0.png
5 └── img_1.png

注意:

JSON 文件也建议放在 assets/ 中,方便统一管理。

在 Compose 中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.rememberLottieComposition

@Composable
fun LottieWithImages() {
val composition by rememberLottieComposition(
spec = LottieCompositionSpec.Asset("vs_success.json"), // JSON 在 assets/ 下
imageAssetsFolder = "images" // 对应 JSON 中的图片目录名
)

LottieAnimation(
composition = composition,
modifier = Modifier.width(600.dp),
)
}

子文件夹

如果我们把导出的文件方便管理,放在子文件夹中

比如放在了app/src/main/assets/vs_success

我们不需要修改生成JSON中的目录名路径,修改也是不行的,直接修改imageAssetsFolder的值就行

1
2
3
4
5
6
7
8
9
10
11
12
@Composable
fun LottieWithImages() {
val composition by rememberLottieComposition(
spec = LottieCompositionSpec.Asset("vs_success/data.json"), // JSON 在 assets/ 下
imageAssetsFolder = "vs_success/images" // 对应 JSON 中的图片目录名
)

LottieAnimation(
composition = composition,
modifier = Modifier.width(600.dp),
)
}

矢量图动画

导入动画文件

矢量动画导出只有一个JSON文件

将你的 .json 动画文件(由 After Effects + LottieFiles 导出)放入:

1
app/src/main/res/raw/your_animation.json

文件名建议全小写,如 loading.jsonsuccess_check.json

在 Compose 中使用

基础用法

基础用法(自动播放、循环)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.airbnb.lottie.compose.*

@Composable
fun LottieExample() {
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.your_animation))
val progress by animateLottieCompositionAsState(composition)

LottieAnimation(
composition = composition,
progress = { progress }, // 或直接传 progress
modifier = Modifier.size(200.dp)
)
}

控制播放行为

控制播放行为(暂停、反向、速度等)

你可以通过 LottieAnimatable 或控制 animateLottieCompositionAsState 的参数来实现高级控制。

示例:点击播放/暂停

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Composable
fun ControllableLottie() {
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.heart_anim))
var isPlaying by remember { mutableStateOf(true) }

val progress by animateLottieCompositionAsState(
composition = composition,
isPlaying = isPlaying,
restartOnPlay = false // 不从头开始
)

Column {
LottieAnimation(
composition = composition,
progress = { progress },
modifier = Modifier.size(150.dp).clickable {
isPlaying = !isPlaying
}
)
Text("点击动画 ${if (isPlaying) "暂停" else "播放"}")
}
}

常用参数说明

参数 说明
composition 通过 rememberLottieComposition 加载的动画资源
progress 动画进度(0f ~ 1f),通常由 animateLottieCompositionAsState 提供
modifier 控制大小、点击等
enableMergePaths 是否启用合并路径(某些动画需要设为 true,但会禁用硬件加速)
dynamicProperties 动态修改颜色、文本等内容(高级用法)

高级:动态修改颜色

高级:动态修改颜色(Dynamic Properties)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
val dynamicProperties = remember {
LottieDynamicProperties(
listOf(
LottieDynamicProperty.Color(
keyPath = arrayOf("Layer", "Shape Group", "Fill 1"),
color = Color.Red.value
)
)
)
}

LottieAnimation(
composition = composition,
progress = { progress },
dynamicProperties = dynamicProperties
)

注意:keyPath 需要根据你的 Lottie JSON 结构确定,可用 LottieFiles 预览器 查看图层名。

性能提示

  • Lottie 在 Compose 中默认使用 软件渲染,复杂动画可能影响性能。
  • 避免在列表(LazyColumn)中频繁创建 rememberLottieComposition,应提升到 ViewModel 或使用 derivedStateOf 缓存。
  • 对于简单图标动画,仍可考虑 AnimatedVectorDrawable(更轻量)。

官方资源