文章目录
一 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:(https://lottiefiles.com/) 是一个独立于Airbnb的平台,设计师可以在上面“上传,测试,购买和下载动画”,而这些只需要你有一个免费的账号。
LottieFiles同时也是一个AE的插件跟Bodymoving类似,只是功能更加丰富,允许我们“预览”动画,上传到LottieFiles平台,保存到我们的电脑上,等等。作为插件的时候比Bodymoving功能更为丰富一些。在线预览平台:https://lottiefiles.com/tools/json-editor
2.3 Why Lottie
效率、还原度高
在没有 Lottie 之前,一般都是通过给开发 PNG 序列帧、GIF,或者是开发自己写,如果遇到复杂的动画,开发一般都会拒绝掉,理由一般都是这个没法实现,或者这个动画需要很多时间,版本迭代周期紧,这个版本没法实现了,要不以后有空给你看看吧… …
2017Lottie出现之后,使设计师能够像传送图片一样轻松地在任何平台上传动画。前设计人员提供视频(动效文件)给开发人员,让开发人员按照要求播放视频文件,即可完成动效的落地。
体积
Lottie 对 APK 大小有什么影响?
非常小:
- ~1600 methods. ~ 1600种方法
- 287kb uncompressed. 287kb 未压缩
Lottie与 GIF 和 PNG 序列相比,体积缩小 600%,传输速度提高 10 倍,Lottie 很小,而且不会像素化(如果只使用矢量素材)。
大部分元素均使用位图,包括科技感的眼镜,与马赛克的流光等,就算使用位图,整体大小也才100KB
研发的优势
iOS、Android、Web 和 React Native 上使用 Lottie 文件。开发人员现在无需为动效在每个平台单独编写代码,从而可以节省数周时间。
- 对于设计师:可以充分发挥创意和设计,可以不用费力讲解复杂的函数曲线和细致的效果,开发能直接 100% 还原动画;不会像 GIF 等手段一样带来超大文件和锯齿边缘,可以流畅实现高清动画。
- 对于开发:可以通过简单的导入和简短的代码,高保真实现复杂动画;而且 lottie 发布之后处于持续更新,任何 issue 都可以很快响应和解决;性能流畅,很少卡顿;集团内已有洛丽塔、lottie 的降级、lottie 的小程序等相关支持。
- 对于 PD:可以在不增加工期的情况下,给产品增加更流畅细腻的动画。
2.4 When Lottie
如果把动效按展示形式分类可以分为,自播放动效与可交互动效。
- 自播放动效(动效内容本身不会产生变化,不需要研发控制动效内容,由设计师完成实现的动效)——建议解决方案:Lottie
- 可交互动效(随着数据的不同会产生变化的动效,需要研发配合设计师完成动效的内容)——不建议使用Lottie
2.5 Lottie不支持的效果
不是所有的动效 lottie 都能实现,希望可以认识到这一点,如果不清楚是否可以实现,可以先熟读 lottie的官方文档:
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 大小有什么影响?
http://airbnb.io/lottie/#/android?id=what-is-the-impact-of-lottie-on-apk-size
非常小:
- ~1600 methods. ~ 1600种方法
- 287kb uncompressed. 287kb 未压缩
源码
例子源码 : https://github.com/LucasXu01/lottiedemo