一、序
Hi,大家好,我是承香墨影!
Lottie 是 Airbnb 开源的一套跨平台的完整解决方案,设计师只需要使用 After Effectes (之后简称 AE)设计出动画之后,使用 Lottic 提供的 Bodymovin 插件将设计好的动画导出成 JSON 格式,就可以直接运用在 ios、android 和 React Native之上,无需关心中间的实现细节。
这样,对于不同的工作角色来说,Lottie 带来的都是更简洁的工作流。开发小哥哥不再担心动画实现困难,设计师小姐姐也不需要担心实现的效果会有偏差。
关于 Lottie 的基本使用,之前也写过一篇文章,不了解的同学可以先看看《聊聊 Airbnb 的 Lottie》。
不过当时的文章有些细节没有讲明白,那就是有时候设计师实现的的动画,其实也是在操作一些图片资源的变换,这样使用 Bodymovin 在 AE 上导出的时候,会同时导出一些图片资源。
那么,如何使用 Lottie 加载一个带图片的动画资源,就是我们今天需要讨论的主题。
二、需要图片资源的动画
今天主要讨论带图片资源的 Lottie 动画。
Lottie 提供的动画资源,其实是可以从很多途径进行加载的,例如你可以放在本地的 assets
目录下,或者放在线上动态下载。
下面我们就分情况来讲解如何加载一个有图片资源的 Lottie 动画,并且最后来说说如何让设计师把图片资源整合到 Lottie 的 JSON 文件中。
2.1 包内资源
有一些不经常变动的动画资源,我们会选择打包在 Apk 中,一般会放在 assets
目录下。
这其实是一种最简单的方式,Lottie 提供了一个 setImageAssetsFolder()
以及 app:imageAssetsFolder
属性,来为我们设置一个 Lottie 动画需要的图片资源在 assets
下的路径。
setImageAssetsFolder()
方法接受一个相对的目录路径,阅读它的文档就知道如何配置了。
接下来我们举个例子来说明问题。
例如,我在 assets 目录下存放了我需要的动画资源,它的目录结构如下。
这个时候,我在布局中写:
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottieView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:imageAssetsFolder="images/"
app:lottie_autoPlay="false"
app:lottie_fileName="question_like.json"
app:lottie_loop="false" />
或者在代码里写(kotlin 示意):
lottieView.imageAssetsFolder = "images/"
lottieView.setAnimation("xinfeng.json")
lottieView.loop(true)
lottieView.playAnimation()
这两种方式都是等效的,最终会去加载我们的动画资源。
在这个动画中有三个图片资源,非常的简单,因为信封图片为白色,所以我将底色调整成了蓝色。
2.2 线上下载资源
最理想的方式是将图片打包在 Apk 中一起发布出去,但是对于一些需要经常变动动画的需求,是无法接受每次发布新版本来替换动画资源的。
这个时候,我们可以选择动态下发动画资源,也就是在需要的时候,提前将动画资源下载到本地的文件系统中。
此时,我们再使用 setImageAssetsFolder()
方法就没有效果了,因为本身图片就已经不在 assets
目录下。
继续在源码中找答案,实际上 Lottie 加载的图片资源,最终会指定到 ImageAssetsManager 的 bitmapForId()
方法,它的实现如下。
关键代码我已经用红框标记出来了,bitmapForId(
) 接收一个 String 类型的 id,它其实就是我们动画资源中,图片资源的名称。而 Lottie 允许我们在加载 assets 目录资源之前,设置一个代理,通过代理的 fetchBitmap()
方法,来提前加载一个图片资源,供 Lottie 动画使用。这里的图片加载代理,可以使用 setImageAssetDelegate()
方法进行设置。
接下来的步骤就简单了,我们从本地的文件系统中,加载一个动画文件的输入流,然后使用 setImageAssetsDelegate()
方法设置一个代理即可。
val fileInputStream = FileInputStream(File("/sdcard/xinfeng.json"))
LottieComposition.Factory.fromInputStream(this,fileInputStream,{ composition ->
lottieView.setComposition(composition!!)
lottieView.setImageAssetDelegate { asset ->
BitmapFactory.decodeStream(assets.open(asset.dirName + asset.fileName))
}
lottieView.loop(true)
lottieView.playAnimation()
})
动画效果和之前一样,就不再过多展示了。
这种方式其实也有点复杂了,因为需要经历一个文件下载,接下来让我们看看一个对开发来说,最简单的方案。
2.3 将图片资源放入 JSON
到这里,我想说,其实 Lottie 动画所需要的图片资源也是可以集成在动画的 JSON 文件中。
如果你能说服设计师,将图片资源整合到动画的 JSON 文件中,那你的工作量就可以节约很多。
接下来我们就来看看如何将图片资源打包到动画的 JSON 文件中。
其实官方文档中,已经给出了非常健全的文档,建议直接把文档发给设计师小姐姐,让她自己体会,开发人员其实也不需要太关心其中的细节。
http://airbnb.io/lottie/after-effects/artwork-to-lottie-walkthrough.html
为了让你能更好的和设计师小姐姐沟通,简单说一下步骤:
- 需要先将图片转换成矢量图 SVG 格式,这个设计师一定有办法。
- 使用 Illustrator 将 SVG 文件另存为 .ai 文件。
- 使用 .ai 文件在 AE 中做动画处理。
- 最后通过 Bodymovin 插件,输出动画资源。
这样,输出的 JSON 里面,其实就已经包含了图片的信息。同时,JSON 文件的大小也会增大,你可以理解是把矢量图打包到了 JSON 文件中,不过这也不完全对。整体来看体积还是非常小的,以现在的例子来说,只是从 3kb 增大到了 15kb。
所以这可以算是一个最优的解决方案,强烈推荐你试着说服设计师小姐姐。
三、设计师校验
如果设计师愿意为你制作没有图片资源的动画 JSON,那设计师如何自己检验自己导出的 JSON 文件是否正确呢?
Lottiefiles 网站提供了一个 preview 的页面,如果你的动画只有一个 JSON 文件,那直接拖拽进去就可以进行预览。
在 Preview 页面可以直接预览,并且右下角还会有一个二维码,可以只用 Lottie 的 Demo App 扫码在手机上预览。
需要注意的是,这种方式,只针对没有图片资源的动画 JSON 才有效。如果是带图片资源的动画,也只能开发自己使用程序实现的方式进行预览!
好了,再遇上 Lottie 动画有图片的时候,知道怎么和设计师沟通了吗?有其他问题欢迎在留言区留言!
今天在公众号后台回复成长『成长』,将会得到我整理的一些学习资料,也能回复『加群』,一起学习进步。
推荐阅读: