Lottie — 是什么,移动应用中的矢量动画

作者: IT Sectr 发布日期: 2026-03-01 阅读时间: 10 分钟

Lottie — 是 Airbnb 的一个开源库,通过 Bodymovin 插件将 Adobe After Effects 中导出的矢量动画以 JSON 格式播放。动画以编程方式渲染,在任何屏幕分辨率下都不会损失质量。根据 GitHub(2026)的数据,Lottie 在 iOS、Android 和 Web 上的超过 50,000 个项目中使用。有关其他动画类型的更多信息,请阅读动画通用指南

要点

  • Lottie — Airbnb 用于 After Effects JSON 矢量动画的库。
  • Bodymovin — 用于将动画从 After Effects 导出到 JSON 的插件。
  • LottieAnimationView — Android(Kotlin/Java)的主要视图组件。
  • AnimationView — iOS(Swift, UIKit/SwiftUI)的主要 UI 组件。
  • .lottie 格式 — 压缩的二进制容器,可将大小减少高达 80%。

什么是 Lottie?

Lottie — 是一个跨平台库,用于播放矢量动画,由 Airbnb 于 2015 年开发。它解决了重型视频文件和光栅精灵表的问题:设计师在 After Effects 中创建动画,通过 Bodymovin 导出到 JSON,然后开发者将此文件嵌入到移动应用中。Lottie 根据平台通过 Canvas、Core Animation 或 Skia 以编程方式渲染动画。

Lottie 的主要优势 — 矢量动画可在任何屏幕上无损缩放:从 Apple Watch 到 4K 电视。JSON 动画文件的大小通常为 5–50 KB,比同等视频文件小几十倍。根据 Airbnb Engineering(2025)的数据,Lottie 支持 Adobe After Effects 超过 80% 的功能,包括蒙版、效果、曲线和表达式。

Bodymovin — 是 After Effects 的一个插件(免费,GitHub),它将合成序列化为 Lottie 运行时能理解的 JSON 格式。支持 After Effects CC 2018 及更新版本。对于具有大量关键帧的复杂动画,建议使用 dotLottie — 一种基于 Lottie JSON 但经过压缩并打包到一个文件中的格式。

Lottie 架构:渲染如何工作

Lottie 使用分层渲染架构,根据平台能力进行调整。在 Android 上,动画通过 Canvas API 绘制 — Lottie 自己的渲染器(LottieDrawable),不使用系统动画。在 iOS 上,Lottie 依赖于 Core Animation Layers,提供高性能和 60 FPS。在 Flutter 上,Lottie 通过 CustomPainter 使用 Skia Canvas。

渲染经过三个阶段:JSON 解析 — 在 LottieComposition 中分析动画(所有图层、形状、关键帧);插值 — 考虑缓动曲线计算关键帧之间的中间值;绘制 — 在 Canvas 上或通过 Core Animation 渲染当前帧。Lottie 支持硬件加速:在 Android 上 — 通过带有 Hardware Accelerator 的 Canvas 加速,在 iOS 上 — 通过带有内置 GPU 加速的 CALayer Core Animation。

平台渲染器硬件加速
AndroidCanvas (LottieDrawable)Hardware Accelerator (API 14+)com.airbnb.lottie
iOSCore Animation (CALayer)GPU (Metal, OpenGL)Lottie-iOS
FlutterSkia Canvas (CustomPainter)Impeller (Flutter 3.16+)lottie_flutter
React NativeNative bridge取决于平台lottie-react-native

在 Android 上使用 Lottie(Kotlin)

在 Android 上,LottieAnimationView 扩展了 AppCompatImageView 并接管了整个加载和渲染循环。JSON 文件放置在 res/raw 或 assets 文件夹中。LottieAnimationView 支持播放管理 — play、pause、resume、setFrame、setProgress、repeat、speed — 以及通过 AnimatorUpdateListener 和 AnimatorListener 进行监听。

xml

<com.airbnb.lottie.LottieAnimationView
    android:id="@+id/animationView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:lottie_rawRes="@raw/loading_animation"
    app:lottie_autoPlay="true"
    app:lottie_loop="true" />
kotlin
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieListener

// 以编程方式配置 LottieAnimationView
val lottieView = LottieAnimationView(context).apply {
    setAnimation(R.raw.celebrate_animation)
    repeatCount = ValueAnimator.INFINITE
    speed = 1.5f
    addAnimatorUpdateListener { animator ->
        val progress = animator.animatedValue as Float
        progressBar.progress = (progress * 100).toInt()
    }
    playAnimation()
}

// 从 assets 加载和缓存
lottieView.setAnimation("animations/confetti.json")
lottieView.setCacheStrategy(LottieAnimationView.CacheStrategy.Strong)

// LottieDrawable — 无需视图的自定义绘制
val drawable = LottieDrawable().apply {
    setComposition(
        LottieCompositionFactory.fromRawRes(context, R.raw.star)
            .addListener { composition -> composition?.let { setComposition(it); play() } }
    )
}

Android 最佳实践:对于经常重复的动画,使用 setCacheStrategy(CacheStrategy.Strong) — 合成缓存在内存中,每个新实例不会重新解析 JSON。对于列表(RecyclerView),使用带有 enableMergePathsForKitKatAndAbove(true) 和 disableExtraScaleModeForOlderWorkarounds() 的 LottieAnimationView 以优化渲染。对于透明背景的动画,设置 android:layerType="hardware" 以启用 GPU 加速。

在 iOS 上使用 Lottie(Swift)

在 iOS 上,AnimationView — 是 Lottie 用于 UIKit 和 SwiftUI 的主要类。它通过 Swift Package Manager 或 CocoaPods 连接。JSON 文件被添加到项目的 bundle 中。AnimationView 自动确定 scale(屏幕的逻辑密度)并使用 Core Animation 以 60 FPS 渲染图层。

swift
import Lottie

// UIKit:带手动控制的 AnimationView
let animationView = AnimationView(name: "confetti")
animationView.frame = view.bounds
animationView.contentMode = .scaleAspectFit
animationView.loopMode = .loop
animationView.animationSpeed = 1.5
animationView.play(fromProgress: 0, toProgress: 0.5) { finished in
    print("动画段已完成:\(finished)")
}
view.addSubview(animationView)

// UIKit:带进度的动画(用于绑定到事件)
animationView.play(fromFrame: AnimationFrameTime(30),
                    toFrame: AnimationFrameTime(90))
swift
// SwiftUI:LottieView 作为 UIViewRepresentable
import Lottie
import SwiftUI

struct LottieView: UIViewRepresentable {
    let name: String
    var loopMode: LottieLoopMode = .loop
    @Binding var progress: CGFloat

    func makeUIView(context: Context) -> AnimationView {
        let view = AnimationView(name: name)
        view.contentMode = .scaleAspectFit
        view.loopMode = loopMode
        return view
    }

    func updateUIView(_ uiView: AnimationView, context: Context) {
        uiView.currentProgress = progress
    }
}

// 在 SwiftUI 中使用
LottieView(name: "loading", progress: $animationProgress)
    .frame(width: 100, height: 100)

iOS 最佳实践:对于加载后立即开始的动画,使用带有 loopMode = .playOnce 的 animationView.play(fromProgress: 0, toProgress: 1) 用于一次性强调效果。对于 UITableView/UICollectionView 中的 Lottie,使用通过 LottieAnimation.cached 缓存动画文件的 AnimationView。渲染大量图层(50+)可能导致 FPS 下降 — 在这种情况下,启用 renderingEngine = .mainThread(默认)或 macOS 的 .coreAnimation。

Lottie 与视频:动画格式比较

Lottie 与视频文件有根本区别:它不存储像素,而是描述矢量形状、它们的转换和随时间变化的曲线。视频(MP4、WebM)— 是固定分辨率的光栅帧序列。差异体现在文件大小、缩放质量、交互性和性能上。

参数Lottie (JSON)视频 (MP4)GIF
文件大小5–50 KB200–2000 KB500–5000 KB
缩放质量矢量(无限)固定(像素)固定
交互性进度、速度、暂停、颜色变化
Alpha 通道(透明度)原生需要编解码器支持
性能(CPU)低负载中等(解码)高(光栅解码)

何时选择 Lottie:加载图标、点赞/反应动画、引导页、按钮强调微动画。对于具有 3D 效果、逼真照明或照片级真实角色的复杂场景,视频仍然是更实用的选择。Lottie 不适合播放长场景(超过 10 秒)— 一个动画的最佳时长为 2–5 秒。

优化 Lottie 性能

Lottie 性能 取决于图层数量、蒙版和效果的复杂性以及渲染器。为了在中端设备上保持 60 FPS,请遵循建议:将每个场景的图层数量限制在 30–40,避免重叠的嵌套预合成,为复杂动画使用 dotLottie。

kotlin
// 针对 RecyclerView 优化 Lottie
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieDrawable
import com.airbnb.lottie.LottieCompositionFactory

// 在内存中缓存合成
private val cache = LottieCompositionFactory.setCacheStrategy(CacheStrategy.Strong)

// LottieAnimationView 池用于重用
class LottiePool {
    private val pool = LinkedList<LottieAnimationView>()

    fun acquire(context: Context): LottieAnimationView {
        return pool.poll() ?: LottieAnimationView(context)
    }

    fun release(view: LottieAnimationView) {
        view.pauseAnimation()
        view.cancelAnimation()
        pool.add(view)
    }
}

// 禁用不必要的功能
lottieView.enableMergePathsForKitKatAndAbove(true)
lottieView.setHardwareAcceleration(true)
lottieView.setMaxFrame(60) // 限制帧数

额外优化:为 Android 4.4+ 设备启用 enableMergePathsForKitKatAndAbove(true) — 这会将重叠的轮廓合并到一条路径中,减少绘制调用次数。使用 dotLottie 替代 JSON — 二进制格式通过 protobuf 序列化将动画压缩 50–80%,从而缩短解析时间。对于 RecyclerView 中的动画,设置 repeatCount = 0(播放一次)并在滚动时通过 recyclerView.addOnScrollListener 停止动画。根据 Airbnb Engineering Blog(2025),这些措施可将 CPU 负载降低高达 40%。

常见问题解答

如何减小 Lottie JSON 的大小?

使用 dotLottie — 基于 protobuf 的二进制格式,可将 JSON 压缩 50–80%。在 After Effects 中通过 Bodymovin 导出时设置「Glyphs」= None(如果不需要文字),关闭额外的参考线和参考线图层。在导出前删除不可见图层和透明度为 0% 的图层。

Lottie 在旧设备上无法播放怎么办?

检查最低 SDK 版本:Android 版 Lottie 支持 API 14+,但某些效果(Path Morphing, Gradient)仅适用于 API 21+。在 iOS 上,Lottie 需要 iOS 11+。对于旧设备,使用后备方案 — 动画中的静态 PNG 帧。通过 LottieCompositionFactory 异步加载动画,并通过 LottieListener.onFailure 处理错误。

可以在 Lottie 动画中动态更改颜色吗?

可以,通过 LottieDynamicPropertiesKeyPath。在 After Effects 中设置图层名称(例如「icon-fill」),然后在代码中:lottieView.addValueCallback(KeyPath(「icon-fill」), LottieProperty.COLOR) { Color.GREEN }。这允许根据应用主题自定义动画,而无需创建重复文件。对于 iOS,使用 AnimationView.setValueProvider(ColorValueProvider)。

Lottie 与 Rive — 有什么区别?

Lottie — 用于播放来自 After Effects 的预制动画的格式。Rive — 具有状态机、触发器和输入的交互式动画。Lottie 适用于被动动画(加载、点赞、欢迎页面)。Rive — 适用于游戏、交互式 UI 元素、对用户操作提供反馈的动画。Rive 需要自己的编辑器,Lottie 通过熟悉的 After Effects 工作。

如何追踪 Lottie 动画的完成?

在 Android 上:lottieView.addAnimatorListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { ... } })。在 iOS 上:animationView.play { finished in }。在 SwiftUI 中:使用带有 onChange 的 Binding 来追踪 currentProgress。对于 Kotlin Multiplatform,使用 lottie-compose 库中的 LottieAnimatable。

总结

  • Lottie — Airbnb 用于播放来自 After Effects 的 JSON 矢量动画的库。
  • Bodymovin — After Effects → JSON 导出插件,免费开源。
  • LottieAnimationView(Android)和 AnimationView(iOS)— 用于嵌入的主要组件。
  • dotLottie (.lottie) 格式通过 protobuf 压缩将文件大小减少高达 80%。
  • Lottie 通过 Canvas(Android)、Core Animation(iOS)或 Skia(Flutter)以 60 FPS 渲染。
  • Lottie 动画的最佳时长 — 2–5 秒,每个场景不超过 30–40 个图层。
  • 对于具有反馈的交互式动画,请使用 Rive,而不是 Lottie。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读