如何高效使用Android动画Lottie实现复杂动画效果?

2026-04-12 13:562阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1592个文字,预计阅读时间需要7分钟。

如何高效使用Android动画Lottie实现复杂动画效果?

Android 动画 Lottie 应用介绍:Lottie 是 Airbnb 开源的一个面向 iOS、Android 和 React Native 的动画库。它允许开发者使用 Adobe After Effects 创建的动画文件(如 .ae 和 .json 格式),将这些动画直接集成到原生 App 中。这样,原生 App 就可以像使用静态素材一样使用这些动画,无需额外的渲染负担。


Android 动画 Lottie 如何使用

一、简介

Lottie 是Airbnb开源的一个面向 iOS、Android、React Native 的动画库,能分析 Adobe After Effects 导出的动画,并且能让原生 App 像使用静态素材一样使用这些动画,完美实现动画效果。

二、Lottie动画文件制作

1.让设计师使用Adobe 的 After Effects(简称 AE)工具(美工一般都会这个)制作这个动画。

2.在AE中安装一个叫做Bodymovin的插件。下载bodymovin,解压缩后只需要\build\extension\bodymovin.zxp这个档案就可以

3.手动安装plugin,以windows系统而言,要先下载 **ExMan Command Line tool**并解压缩。 再来把下载的bodymovin压缩后的 bodymovin-master\build\extension 目录下的bodymovin.zxp 这个档案复制进去同一个资料夹。

4.去找cmd,并以系统管理员身分执行。

5.打“cd C:/ExManCmd_win所在的路径“,进入ExManCmd的资料夹中

6.接着打 ExManCmd.exe /install bodymovin.zxp 就完

7.再来进入AE 后,可以在windows/extentions/bodymovin 找到插件,开启后按下Render 就完成了。重点来了,这时会在你选的Destination Folder目录中生成一个json格式的文件,这个 json 文件描述了该动画的一些关键点的坐标以及运动轨迹。

三、如何使用Lottie

Lottie支持多平台,使用同一个JSON动画文件,可在不同平台实现相同的效果。支持Android,ios,前段。

1.依赖

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

dependencies { compile 'com.airbnb.android:lottie:2.1.0' }

2.动画文件

第一种方法,将我们所需要的动画文件loading.json保存在app/src/main/assets文件里。 第二种方法,网络上AE生成的动画文件。

3.使用

在布局文件中使用

如何高效使用Android动画Lottie实现复杂动画效果?

<com.airbnb.lottie.LottieAnimationView android:id="@+id/animation_view" android:layout_width="400dp" android:layout_height="400dp" app:lottie_fileName="loading.json" app:lottie_loop="true" app:lottie_autoPlay="true"/>

使用网络加载AE生成的动画文件json

private void loadUrl(String url) { client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { try { JSONObject json = new JSONObject(response.body().string()); LottieComposition.Factory .fromJson(getResources(), json, new OnCompositionLoadedListener() { @Override public void onCompositionLoaded(LottieComposition composition) { setComposition(composition); } }); } catch (JSONException e) { } } } }); } private void setComposition(LottieComposition composition){ animation_view.setProgress(0); animation_view.loop(true); animation_view.setComposition(composition); animation_view.playAnimation(); }

四、Lottie实现原理

设计师把一张复杂的图片使用多个图层来表示,每个图层展示一部分内容,图层中的内容也可以拆分为多个元素。拆分元素之后,根据动画需求,可以单独对图层或者图层中的元素做平移、旋转、收缩等动画。

Lottie的使用的资源是需要先通过bodymovin( bodymovin 插件本身是用于网页上呈现各种AE效果的一个开源库)将 Adobe After Effects (AE)生成的aep动画工程文件转换为通用的json格式描述文件。Lottie则负责解析动画的数据,计算每个动画在某个时间点的状态,准确地绘制到屏幕上。

Lottie主要类图:

Lottie对外通过控件LottieAnimationView暴露接口,控制动画。

LottieAnimationView继承自ImageView,通过当前时间绘制canvas显示到界面上。这里有两个关键类:LottieComposition 负责解析json描述文件,把json内容转成Java数据对象;LottieDrawable负责绘制,把LottieComposition转成的数据对象绘制成drawable显示到View上。顺序如下:

解析json外部结构LottieComposition封装整个动画的信息,包括动画大小,动画时长,帧率,用到的图片,字体,图层等等。

{ "v": "4.6.0", //bodymovin的版本 "fr": 29.9700012207031, //帧率 "ip": 0, //起始关键帧 "op": 141.000005743048, //结束关键帧 "w": 800, //动画宽度 "h": 800, //动画高度 "ddd": 0, "assets": [...] //资源信息 "layers": [...] //图层信息 }

解析图片资源

"assets": [ //资源信息 { //第一张图片 "id": "image_0", //图片id "w": 58, //图片宽度 "h": 31, //图片高度 "u": "images/", //图片路径 "p": "img_0.png" //图片名称 }, {...} //第n张图片 ]

解析图层

"layers": [ //图层信息 { //第一层动画 "ddd": 0, "ind": 0, //layer id 图层 id "ty": 4, //图层类型 "nm": "center_circle", "ks": {...}, //动画 "ao": 0, "shapes": [...], "ip": 0, //inFrame 该图层起始关键帧 "op": 90, //outFrame 该图层结束关键帧 "st": 0, //startFrame 开始 "bm": 0, "sr": 1 }, {...} //第n层动画 ]

如何动起来时序图

利用属性动画控制进度,每次进度改变通知到每一层,触发LottieAnimationView重绘。代码如下:

public LottieDrawable() { animator.setRepeatCount(0); animator.setInterpolator(new LinearInterpolator()); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { if (systemAnimationsAreDisabled) { animator.cancel(); setProgress(1f); } else { setProgress((float) animation.getAnimatedValue()); } } }); }

通过CompositionLayer把进度传递到各个图层

@Override public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) { super.setProgress(progress); if (timeRemapping != null) { long duration = lottieDrawable.getComposition().getDuration(); long remappedTime = (long) (timeRemapping.getValue() * 1000); progress = remappedTime / (float) duration; } if (layerModel.getTimeStretch() != 0) { progress /= layerModel.getTimeStretch(); } progress -= layerModel.getStartProgress(); for (int i = layers.size() - 1; i >= 0; i--) { layers.get(i).setProgress(progress); } }

通知进度改变

void setProgress(@FloatRange(from = 0f, to = 1f) float progress) { if (progress < getStartDelayProgress()) { progress = 0f; } else if (progress > getEndProgress()) { progress = 1f; } if (progress == this.progress) { return; } this.progress = progress; for (int i = 0; i < listeners.size(); i++) { listeners.get(i).onValueChanged(); } }

最终回调到LottieAnimationView的invalidateDrawable

@Override public void invalidateDrawable(@NonNull Drawable dr) { if (getDrawable() == lottieDrawable) { // We always want to invalidate the root drawable so it redraws the whole drawable. // Eventually it would be great to be able to invalidate just the changed region. super.invalidateDrawable(lottieDrawable); } else { // Otherwise work as regular ImageView super.invalidateDrawable(dr); } }

最后触发LottieDrawable重绘

@Override public void draw(@NonNull Canvas canvas) { ... matrix.reset(); matrix.preScale(scale, scale); compositionLayer.draw(canvas, matrix, alpha); //这里会调用所有layer的绘制方法 if (hasExtraScale) { canvas.restore(); } }

总结

1.劣势
(1)性能不够好—某些动画特效,内存和性能不够好;相对于属性动画,在展示大动画时,帧率较低

2.优势
(1)开发效率高—代码实现简单,更换动画方便,易于调试和维护。
(2)数据源多样性—可从assets,sdcard,网络加载动画资源,能做到不发版本,动态更新
(3)跨平台—设计稿导出一份动画描述文件,android,ios,react native通用
(4) Lottie使用简单,易于上手,非常值得尝试。

本文共计1592个文字,预计阅读时间需要7分钟。

如何高效使用Android动画Lottie实现复杂动画效果?

Android 动画 Lottie 应用介绍:Lottie 是 Airbnb 开源的一个面向 iOS、Android 和 React Native 的动画库。它允许开发者使用 Adobe After Effects 创建的动画文件(如 .ae 和 .json 格式),将这些动画直接集成到原生 App 中。这样,原生 App 就可以像使用静态素材一样使用这些动画,无需额外的渲染负担。


Android 动画 Lottie 如何使用

一、简介

Lottie 是Airbnb开源的一个面向 iOS、Android、React Native 的动画库,能分析 Adobe After Effects 导出的动画,并且能让原生 App 像使用静态素材一样使用这些动画,完美实现动画效果。

二、Lottie动画文件制作

1.让设计师使用Adobe 的 After Effects(简称 AE)工具(美工一般都会这个)制作这个动画。

2.在AE中安装一个叫做Bodymovin的插件。下载bodymovin,解压缩后只需要\build\extension\bodymovin.zxp这个档案就可以

3.手动安装plugin,以windows系统而言,要先下载 **ExMan Command Line tool**并解压缩。 再来把下载的bodymovin压缩后的 bodymovin-master\build\extension 目录下的bodymovin.zxp 这个档案复制进去同一个资料夹。

4.去找cmd,并以系统管理员身分执行。

5.打“cd C:/ExManCmd_win所在的路径“,进入ExManCmd的资料夹中

6.接着打 ExManCmd.exe /install bodymovin.zxp 就完

7.再来进入AE 后,可以在windows/extentions/bodymovin 找到插件,开启后按下Render 就完成了。重点来了,这时会在你选的Destination Folder目录中生成一个json格式的文件,这个 json 文件描述了该动画的一些关键点的坐标以及运动轨迹。

三、如何使用Lottie

Lottie支持多平台,使用同一个JSON动画文件,可在不同平台实现相同的效果。支持Android,ios,前段。

1.依赖

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

dependencies { compile 'com.airbnb.android:lottie:2.1.0' }

2.动画文件

第一种方法,将我们所需要的动画文件loading.json保存在app/src/main/assets文件里。 第二种方法,网络上AE生成的动画文件。

3.使用

在布局文件中使用

如何高效使用Android动画Lottie实现复杂动画效果?

<com.airbnb.lottie.LottieAnimationView android:id="@+id/animation_view" android:layout_width="400dp" android:layout_height="400dp" app:lottie_fileName="loading.json" app:lottie_loop="true" app:lottie_autoPlay="true"/>

使用网络加载AE生成的动画文件json

private void loadUrl(String url) { client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { try { JSONObject json = new JSONObject(response.body().string()); LottieComposition.Factory .fromJson(getResources(), json, new OnCompositionLoadedListener() { @Override public void onCompositionLoaded(LottieComposition composition) { setComposition(composition); } }); } catch (JSONException e) { } } } }); } private void setComposition(LottieComposition composition){ animation_view.setProgress(0); animation_view.loop(true); animation_view.setComposition(composition); animation_view.playAnimation(); }

四、Lottie实现原理

设计师把一张复杂的图片使用多个图层来表示,每个图层展示一部分内容,图层中的内容也可以拆分为多个元素。拆分元素之后,根据动画需求,可以单独对图层或者图层中的元素做平移、旋转、收缩等动画。

Lottie的使用的资源是需要先通过bodymovin( bodymovin 插件本身是用于网页上呈现各种AE效果的一个开源库)将 Adobe After Effects (AE)生成的aep动画工程文件转换为通用的json格式描述文件。Lottie则负责解析动画的数据,计算每个动画在某个时间点的状态,准确地绘制到屏幕上。

Lottie主要类图:

Lottie对外通过控件LottieAnimationView暴露接口,控制动画。

LottieAnimationView继承自ImageView,通过当前时间绘制canvas显示到界面上。这里有两个关键类:LottieComposition 负责解析json描述文件,把json内容转成Java数据对象;LottieDrawable负责绘制,把LottieComposition转成的数据对象绘制成drawable显示到View上。顺序如下:

解析json外部结构LottieComposition封装整个动画的信息,包括动画大小,动画时长,帧率,用到的图片,字体,图层等等。

{ "v": "4.6.0", //bodymovin的版本 "fr": 29.9700012207031, //帧率 "ip": 0, //起始关键帧 "op": 141.000005743048, //结束关键帧 "w": 800, //动画宽度 "h": 800, //动画高度 "ddd": 0, "assets": [...] //资源信息 "layers": [...] //图层信息 }

解析图片资源

"assets": [ //资源信息 { //第一张图片 "id": "image_0", //图片id "w": 58, //图片宽度 "h": 31, //图片高度 "u": "images/", //图片路径 "p": "img_0.png" //图片名称 }, {...} //第n张图片 ]

解析图层

"layers": [ //图层信息 { //第一层动画 "ddd": 0, "ind": 0, //layer id 图层 id "ty": 4, //图层类型 "nm": "center_circle", "ks": {...}, //动画 "ao": 0, "shapes": [...], "ip": 0, //inFrame 该图层起始关键帧 "op": 90, //outFrame 该图层结束关键帧 "st": 0, //startFrame 开始 "bm": 0, "sr": 1 }, {...} //第n层动画 ]

如何动起来时序图

利用属性动画控制进度,每次进度改变通知到每一层,触发LottieAnimationView重绘。代码如下:

public LottieDrawable() { animator.setRepeatCount(0); animator.setInterpolator(new LinearInterpolator()); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { if (systemAnimationsAreDisabled) { animator.cancel(); setProgress(1f); } else { setProgress((float) animation.getAnimatedValue()); } } }); }

通过CompositionLayer把进度传递到各个图层

@Override public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) { super.setProgress(progress); if (timeRemapping != null) { long duration = lottieDrawable.getComposition().getDuration(); long remappedTime = (long) (timeRemapping.getValue() * 1000); progress = remappedTime / (float) duration; } if (layerModel.getTimeStretch() != 0) { progress /= layerModel.getTimeStretch(); } progress -= layerModel.getStartProgress(); for (int i = layers.size() - 1; i >= 0; i--) { layers.get(i).setProgress(progress); } }

通知进度改变

void setProgress(@FloatRange(from = 0f, to = 1f) float progress) { if (progress < getStartDelayProgress()) { progress = 0f; } else if (progress > getEndProgress()) { progress = 1f; } if (progress == this.progress) { return; } this.progress = progress; for (int i = 0; i < listeners.size(); i++) { listeners.get(i).onValueChanged(); } }

最终回调到LottieAnimationView的invalidateDrawable

@Override public void invalidateDrawable(@NonNull Drawable dr) { if (getDrawable() == lottieDrawable) { // We always want to invalidate the root drawable so it redraws the whole drawable. // Eventually it would be great to be able to invalidate just the changed region. super.invalidateDrawable(lottieDrawable); } else { // Otherwise work as regular ImageView super.invalidateDrawable(dr); } }

最后触发LottieDrawable重绘

@Override public void draw(@NonNull Canvas canvas) { ... matrix.reset(); matrix.preScale(scale, scale); compositionLayer.draw(canvas, matrix, alpha); //这里会调用所有layer的绘制方法 if (hasExtraScale) { canvas.restore(); } }

总结

1.劣势
(1)性能不够好—某些动画特效,内存和性能不够好;相对于属性动画,在展示大动画时,帧率较低

2.优势
(1)开发效率高—代码实现简单,更换动画方便,易于调试和维护。
(2)数据源多样性—可从assets,sdcard,网络加载动画资源,能做到不发版本,动态更新
(3)跨平台—设计稿导出一份动画描述文件,android,ios,react native通用
(4) Lottie使用简单,易于上手,非常值得尝试。