Lottie系列一:介绍与使用

1,405

@[toc]

一 Lottie

Lottie 是Airbnb开源的一个面向Android、 iOS、 Web、 Windows 的动画库,可以实时渲染After Effects动画。所以AE动画中,Lottie插件常用来配合输出JSON动画文件。

二 Lottie起源&社区

2.1起源

21世纪初,flash是网页动画之王,其规范约束随意,其中很多可能都没有符合用户体验设计原则,随着flash的消失,HTML成为使用标准以及用户体验的规范化,但在网页上落地一个动画所付出的努力和工作实在是太高了,设计师做出的动画给到开发,能实现的效果非常有限。除了成本高和繁琐外,从头开始用代码创建动画也会导致与设计稿相差甚远。直到Lottie出现,才迎来了转机。

Hernan Torrisi在2015年提出了在AE中导出动画的想法,使用他创建的一个叫Bodymovin的插件,能够导出JSON描述的动画。他还发布了史上第一个支持该格式的渲染器,并为浏览器提供了一个基于JS的播放器。

在2017年,Airbnb的工程师看到了基于JSON的动画潜力,编写了可以渲染JSON文件的iOS和Android库,他们称之为“Lottie”。 Airbnb的开发者将其作为一个开源平台,不仅是为了免费发布,也是为了打造一个社区。

2.2 社区

LottieFiles:(lottiefiles.com/) 是一个独立于Airbnb的平台,设计师可以在上面“上传,测试,购买和下载动画”,而这些只需要你有一个免费的账号。 LottieFiles同时也是一个AE的插件跟Bodymoving类似,只是功能更加丰富,允许我们“预览”动画,上传到LottieFiles平台,保存到我们的电脑上,等等。作为插件的时候比Bodymoving功能更为丰富一些。在线预览平台:lottiefiles.com/tools/json-…

2.3 Why Lottie

效率、还原度高

111

在没有 Lottie 之前,一般都是通过给开发 PNG 序列帧、GIF,或者是开发自己写,如果遇到复杂的动画,开发一般都会拒绝掉,理由一般都是这个没法实现,或者这个动画需要很多时间,版本迭代周期紧,这个版本没法实现了,要不以后有空给你看看吧... ...

222

2017Lottie出现之后,使设计师能够像传送图片一样轻松地在任何平台上传动画。前设计人员提供视频(动效文件)给开发人员,让开发人员按照要求播放视频文件,即可完成动效的落地。

体积

Lottie 对 APK 大小有什么影响?

非常小:

  • ~1600 methods. ~ 1600种方法
  • 287kb uncompressed. 287kb 未压缩

Lottie与 GIF 和 PNG 序列相比,体积缩小 600%,传输速度提高 10 倍,Lottie 很小,而且不会像素化(如果只使用矢量素材)。

640 640

大部分元素均使用位图,包括科技感的眼镜,与马赛克的流光等,就算使用位图,整体大小也才100KB

研发的优势

iOS、Android、Web 和 React Native 上使用 Lottie 文件。开发人员现在无需为动效在每个平台单独编写代码,从而可以节省数周时间。

  • 对于设计师:可以充分发挥创意和设计,可以不用费力讲解复杂的函数曲线和细致的效果,开发能直接 100% 还原动画;不会像 GIF 等手段一样带来超大文件和锯齿边缘,可以流畅实现高清动画。
  • 对于开发:可以通过简单的导入和简短的代码,高保真实现复杂动画;而且 lottie 发布之后处于持续更新,任何 issue 都可以很快响应和解决;性能流畅,很少卡顿;集团内已有洛丽塔、lottie 的降级、lottie 的小程序等相关支持。
  • 对于 PD:可以在不增加工期的情况下,给产品增加更流畅细腻的动画。

2.4 When Lottie

如果把动效按展示形式分类可以分为,自播放动效与可交互动效。

  1. 自播放动效(动效内容本身不会产生变化,不需要研发控制动效内容,由设计师完成实现的动效)——建议解决方案:Lottie
  2. 可交互动效(随着数据的不同会产生变化的动效,需要研发配合设计师完成动效的内容)——不建议使用Lottie

2.5 Lottie不支持的效果

不是所有的动效 lottie 都能实现,希望可以认识到这一点,如果不清楚是否可以实现,可以先熟读 lottie的官方文档:

Supported Features

2.6 官方Demo和在线预览平台

下载市场

https://lottiefiles.com/

安卓example

http://airbnb.io/lottie/#/android?id=sample-app

在线预览平台

https://lottiefiles.com/tools/json-editor

三 使用介绍

3.1 基础使用

添加依赖:

implementation \'com.airbnb.android:lottie:5.2.0\'

添加视图

    <com.airbnb.lottie.LottieAnimationView
        android:id="@+id/animationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:lottie_fileName="popeye.json"
        app:lottie_autoPlay="true"
        app:lottie_loop="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

把用到的JSON文件放在assets文件夹下,如果导出时有images文件夹,一并放入assets文件夹;

  • lottie_fileName属性:本地加载时指定JSON文件名,默认从assets文件夹中查找JSON文件。如果在aasets文件夹下找不到对应的JSON文件,就会抛出异常。文件除了可以使用.json格式以外,还可以使用.zip格式的压缩文件
  • lottie_imageAssetsFolder属性:指定Lottie中图在assets目录下的哪个文件中。比如指定路径是Images/,程序就会去assets/Images/下查找。
  • lottie_autoPlay是指是否自动播放,true就自动播放,反之不是,不指定默认false
  • lottie_loop是否循环播放,默认fasle,只播放一次

3.2 加载的资源来源:

  • Src/main/res/raw 中的 json 动画。
  • Src/main/asset 中的 json 文件。
  • Src/main/asset 中的 zip 文件。
  • Src/main/asset 中的 dotLottie 文件。
  • 指向 json 或 zip 文件的 URL。
  • 一个 json 字符串。源可以来自任何东西,包括您自己的网络堆栈。
  • 到 json 文件或 zip 文件的 InputStream。

3.3 LottieAnimationView自定义属性

lottie_rawRes:进行本地加载时也可以放在raw文件夹下,该属性用于指定在res->raw文件夹下的JSON文件名(不带.json后缀);lottie_fileName和lottie_rawRes不能同时设置,不然会报错。官方更建议使用 lottie _ rawRes,因为可以通过 R 使用对动画的静态引用,而不仅仅使用字符串名称。

lottie_repeatMode:指定循环播放的循序,取值为repeat或reverse,repeat表示正常顺序播放,reverse表示倒序播放。

lottie_repeatCount :指定循环次数,取值为整数类型

lottie_progress:用于指定动画初次显示时的进度,类型为float,取值范围为0~1。

    <com.airbnb.lottie.LottieAnimationView
        android:id="@+id/animationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:lottie_rawRes="@raw/popeye"
        app:lottie_progress="0.5"
        />

因为没有设置自动播放和循环播放,所以动画就会固定在进度为50%的位置。如果设置了自动播放和循环播放,则会看不到初始化设置的进度效果。

LottieAnimationView可设属性:

<resources>
    <attr format="reference" name="lottieAnimationViewStyle"/>
    <item name="lottie_layer_name" type="id"/>
    <declare-styleable name="LottieAnimationView">
        <attr format="string" name="lottie_fileName"/>
        <attr format="reference" name="lottie_rawRes"/>
        <attr format="string" name="lottie_url"/>
        <attr format="reference" name="lottie_fallbackRes"/>
        <attr format="boolean" name="lottie_autoPlay"/>
        <attr format="boolean" name="lottie_loop"/>
        <attr format="enum" name="lottie_repeatMode">
            <enum name="restart" value="1"/>
            <enum name="reverse" value="2"/>
        </attr>
        <attr format="integer" name="lottie_repeatCount"/>
        <attr format="string" name="lottie_imageAssetsFolder"/>
        <attr format="float" name="lottie_progress"/>
        <attr format="boolean" name="lottie_enableMergePathsForKitKatAndAbove"/>
        <attr format="color" name="lottie_colorFilter"/>
        <attr format="float" name="lottie_speed"/>
        <attr format="boolean" name="lottie_cacheComposition"/>
        <attr format="boolean" name="lottie_ignoreDisabledSystemAnimations"/>
        <attr format="boolean" name="lottie_clipToCompositionBounds"/>
        <!-- These values must be kept in sync with the RenderMode enum -->
        <attr format="enum" name="lottie_renderMode">
            <enum name="automatic" value="0"/>
            <enum name="hardware" value="1"/>
            <enum name="software" value="2"/>
        </attr>
    </declare-styleable>
</resources>

java代码设置:

LottieAnimationView animationView = (LottieAnimationView)findViewById(R.id.animation_view);
// 布局中不指定文件可以在此设置,路径设置同布局文件
animationView.setAnimation("hello-world.json");
// 是否循环播放
animationView.loop(true);
// 设置播放速率,例如:2代表播放速率是不设置时的二倍
animationView.setSpeed(2f);
// 开始播放
animationView.playAnimation();
 // 暂停播放
animationView.pauseAnimation();
// 取消播放
animationVIew.cancelAnimation();
// 设置播放进度
animationView.setProgress(0.5f);
// 判断是否正在播放
animationView.isAnimating();

setAnimation()有六种方法,可以直接设置动画的Json对象,或者设置Json文件相对路径名:

setAnimation(@RawRes final int rawRes)
setAnimation(final String assetName) 
setAnimationFromJson(String jsonString) //不建议使用
setAnimationFromJson(String jsonString, @Nullable String cacheKey)
setAnimation(JsonReader reader, @Nullable String cacheKey)
setAnimationFromUrl(String url)

3.4 动画

动画监听器

animationView.addAnimatorUpdateListener { animation ->
}
animationView.addAnimatorListener(...)
animationView.addPauseListener {
}

定制动画效果

尽管 playAnimation ()对于绝大多数用例来说已经足够了,但是您可以在更新回调中为您自己的 Animator 调用 setProgress (...)。这对于将动画与手势、下载进度或滚动位置等绑定非常有用。

// Custom animation speed or duration.
val animator = ValueAnimator.ofFloat(0f, 1f)
animator.addUpdateListener {
    animationView.setProgress(animation.animatedValue)
}
animator.start()

四 缓存和全局配置

4.1 动画缓存

默认情况下,所有 Lottie 动画都使用 LRU 缓存缓存。将为从 res/raw/或 asset/加载的动画创建默认缓存键(a cache key)。其他 API 需要设置缓存键。如果您为同一个动画并行地激发多个动画请求,比如回收视图中的一个愿望列表中心,那么后续的请求将加入现有的任务,因此它只被解析一次。

4.2 全局配置

当从网络加载动画时,使用你自己的网络堆栈而不是 Lottie 内置的网络堆栈;

为从网络获取的动画提供您自己的缓存目录,而不是使用 Lottie 的默认目录(cacheDir/Lottie _ network _ cache)。

启用系统设计器进行调试

Lottie.initialize(
    LottieConfig.Builder()
        .setEnableSystraceMarkers(true)
        .setNetworkFetcher(...)
        .setNetworkCacheDir(...)
)

五 Lottie vs Android Vector Drawable (AVD)

Lottie优势

  • 支持一个更大的After Effects features特性集。参见完整列表 supported features 的支持特性。
  • 手动设置进度,将动画挂接到手势、事件等。
  • 从网络下载动画
  • 动态回放速度
  • Masks是反锯齿的
  • 动态更改动画的特定部分的颜色

AVD优势

  • 由于在 RenderThread 上运行的动画与主线程相比性能更快。

六 Lottie 对 APK 大小有什么影响?

(airbnb.io/lottie/#/an…)

非常小:

  • ~1600 methods. ~ 1600种方法
  • 287kb uncompressed. 287kb 未压缩

源码

例子源码 : https://github.com/LucasXu01/lottiedemo

参考

Lottie官网

Lottie进阶和原理分析

支持点击交互的Lottie-Android

Lottie—json文件解析

Lottie动画使用及原理分析

如何在Lottie动画中获得可用的总帧数

Flutter进阶教程——Flutter中使用Lottie动画

从设计师和开发的角度使用Lottie