2

Lottie简介

Lottie
Lottie是一个iOS,Android和React Native库,可以实时渲染After Effects动画,允许应用程序像使用静态图像一样轻松使用动画。

为什么使用Lottie?

灵活的After Effects功能

Lottie目前支持实体,形状图层,蒙版,alpha遮罩,修剪路径和虚线图案。Lottie将定期添加新功能。

以更让人喜欢的方式操纵动画

Lottie动画可以前进、后退,并且最重要的是可以对动画进行编程以响应任何交互。

动画文件小

在应用中捆绑矢量动画,而不必担心多个维度或大文件大小。或者可以通过从JSON API加载动画文件来完全将动画文件与应用程序代码分离。

Android引入Lottie

使用准备

Lottie支持多平台,使用同一个JSON动画文件,可在不同平台实现相同的效果。Android 通过Airbnb的开源项目lottie-android实现,最低支持 API 16;
在项目的 build.gradle 文件添加依赖

dependencies {
  implementation 'com.airbnb.android:lottie:$lottieVersion'
}

在项目的 build.gradle 文件添加依赖

核心类

  • LottieAnimationView继承ImageView,是加载Lottie动画的默认和最简单的方法
  • LottieDrawable与LottieAnimationView具有大多数相同的API,但可以在任何所需View上使用它。
  • LottieComposition动画json数据的对象模型,通过LottieComposition,实现对动画的分解和序列化。

加载动画

Lottie动画可以从以下几处加载:

  • 存放在src/main/res/raw下的json动画文件
  • 存放在src/main/assets下的json文件
  • 存放在src/main/assets下的zip文件
  • 通过一个url获取到的json或者zip文件
  • 一个json字符串,可以来自于任何地方,包括网络
  • 一个输出json或者zip文件的InputStream

XML方式加载动画

最简单的使用方法是使用LottieAnimationView:
建议使用lottie_rawRes,因为可以通过R使用对动画的静态引用,而不是仅使用字符串名称。

From res/raw (lottie_rawRes) or assets/ (lottie_fileName)
<com.airbnb.lottie.LottieAnimationView
        android:id="@+id/animation_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        app:lottie_rawRes="@raw/hello_world"
        // or
        app:lottie_fileName="hello_world.json"

        // Loop indefinitely
        app:lottie_loop="true"
        // Start playing as soon as the animation is loaded
        app:lottie_autoPlay="true" />

编程方式加载动画

可以查看LottieAnimationView类的API进行编程方式播放动画,具体代码不再赘述

Lottie动画还支持更多特性:动画监听器、动画循环、缩放等此处不再赘述,有需要请参考:http://airbnb.io/lottie/#/android

踩坑(遇到的问题)

动画文件版本问题

UI首次给我物料时立即放到工程里试了一下,发现报错如下:

java.lang.IllegalStateException: Missing values for keyframe.
        at com.airbnb.lottie.animation.keyframe.FloatKeyframeAnimation.getValue(FloatKeyframeAnimation.java:16)
        at com.airbnb.lottie.animation.keyframe.FloatKeyframeAnimation.getValue(FloatKeyframeAnimation.java:8)
        at com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation.getValue(BaseKeyframeAnimation.java:125)
        at com.airbnb.lottie.animation.keyframe.TransformKeyframeAnimation.getMatrix(TransformKeyframeAnimation.java:113)

经过搜索发现了一个官方的issues:https://github.com/airbnb/lottie-android/issues/1177
有一个哥们回复如下:Lottie 3.0和Bodymovin 5.5有一些重要的json优化,可以节省json大小和解析速度的1/3。 但是,必须在3.0以上生效,否则就在bodymovin设置中启用“导出为旧格式”(Bodymovin为AE导出动画的插件)。
看了一下我们的版本果然为3.0一下(2.5.6),于是跟UI说明,重新导出了一份动画物料,问题解决。

zip动画文件多次播放崩溃

UI给我的是一个zip文件,由于Lottie也支持zip所以就直接把zip文件放到assets目录下适使用,第一次进入效果很好,但是退出Activity再次进来就会报错,错误信息如下:

java.lang.IllegalStateException: You must set an images folder before loading an image. Set it with LottieComposition#setImagesFolder or LottieDrawable#setImagesFolder
        at com.airbnb.lottie.manager.ImageAssetManager.bitmapForId(ImageAssetManager.java:107)
        at com.airbnb.lottie.LottieDrawable.getImageAsset(LottieDrawable.java:839)
        at com.airbnb.lottie.model.layer.ImageLayer.getBitmap(ImageLayer.java:68)
        at com.airbnb.lottie.model.layer.ImageLayer.drawLayer(ImageLayer.java:32)
        at com.airbnb.lottie.model.layer.BaseLayer.draw(BaseLayer.java:201)
        at com.airbnb.lottie.model.layer.CompositionLayer.drawLayer(CompositionLayer.java:100)
        at com.airbnb.lottie.model.layer.BaseLayer.draw(BaseLayer.java:201)
        at com.airbnb.lottie.LottieDrawable.draw(LottieDrawable.java:319)

很幸运的是这个bug我也找到了官方的issueshttps://github.com/airbnb/lottie-android/issues/1009,有一个committer回复在新版本已经修复了这个bug,修复到了3.0版本,看代码提交记录大概是bitmap回收的bug。由于我们的版本是2.5.6因此存在此bug,但是升级Lottie的成本比较大,UI又倾向于使用Lottie,这个问题很难办。抱着试一试的态度把zip解压了,放到assets目录下居然没有问题了。!
wtf.jpg


Jacy
29 声望2 粉丝