1

一、序

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...

为了让你能更好的和设计师小姐姐沟通,简单说一下步骤:

  1. 需要先将图片转换成矢量图 SVG 格式,这个设计师一定有办法。
  2. 使用 Illustrator 将 SVG 文件另存为 .ai 文件。
  3. 使用 .ai 文件在 AE 中做动画处理。
  4. 最后通过 Bodymovin 插件,输出动画资源。

这样,输出的 JSON 里面,其实就已经包含了图片的信息。同时,JSON 文件的大小也会增大,你可以理解是把矢量图打包到了 JSON 文件中,不过这也不完全对。整体来看体积还是非常小的,以现在的例子来说,只是从 3kb 增大到了 15kb。

所以这可以算是一个最优的解决方案,强烈推荐你试着说服设计师小姐姐。

三、设计师校验

如果设计师愿意为你制作没有图片资源的动画 JSON,那设计师如何自己检验自己导出的 JSON 文件是否正确呢?

Lottiefiles 网站提供了一个 preview 的页面,如果你的动画只有一个 JSON 文件,那直接拖拽进去就可以进行预览。

https://www.lottiefiles.com/p...

在 Preview 页面可以直接预览,并且右下角还会有一个二维码,可以只用 Lottie 的 Demo App 扫码在手机上预览。

需要注意的是,这种方式,只针对没有图片资源的动画 JSON 才有效。如果是带图片资源的动画,也只能开发自己使用程序实现的方式进行预览!

好了,再遇上 Lottie 动画有图片的时候,知道怎么和设计师沟通了吗?有其他问题欢迎在留言区留言!

今天在公众号后台回复成长『成长』,将会得到我整理的一些学习资料,也能回复『加群』,一起学习进步。

推荐阅读:


plokmju88
1.5k 声望132 粉丝

大家好,我是承香墨影。