Lottie
1.简介
最近在做公司项目时候,有涉及到加载动画文件,看到以前的项目使用的是Lottie这个库。
Lottie是一个很多平台都可以用的三方库,按照官网的原话简介如下,这里主要整理记录一下Android端的使用。
Lottie 是一个适用于 Android、iOS、Web 和 Windows 的库,它解析 Adobe After Effects 导出的 JSON 格式动画(使用 Bodymovin),并在移动设备和网页上原生渲染它们!
2.使用
话不多说,直接开用。
lottie有指定运行的动画格式:就是json。
2.1导库:
建议用最新版本,因为老版本踩过坑,后面解释
groovy
dependencies {
...
implementation "com.airbnb.android:lottie:$lottieVersion"
...
}
2.2 LottieAnimationView
LottieAnimationView是最简单、最直接的使用方式,继承自ImageView,可以在xml布局文件里面定义
xml
<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" //R.raw
// or
app:lottie_fileName="hello_world.json" //assets
// 循环动画
app:lottie_loop="true"
// 加载完成立马动画
app:lottie_autoPlay="true" />
加载json动画文件的方式主要为以下两种:
- 在resource目录下的raw目录(⭐)
- 在assets目录
推荐第一种,可以通过R静态引用资源文件,非常利于管理和访问:

代码层面设置也是ok的,这样更符合实际开发情况,动态加载动画
java
lottieAnimationView = findViewById(R.id.lottie);
lottieAnimationView.setAnimation(R.raw.confor);
lottieAnimationView.setRepeatCount(-1);
lottieAnimationView.playAnimation();
lottieview还可以设置静态资源,完全可以当成ImageView来用。
java
lottieAnimationView.setImageResource(R.drawable.ic_launcher);
动画回调
想要在动画运行前、后、取消时候进行处理,可以通过回调实现,这个看具体的开发逻辑
java
lottieAnimationView.addAnimatorListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(@NonNull Animator animation) {
lottieAnimationView.setSpeed(-1);//动画开始前设置到放
}
@Override
public void onAnimationEnd(@NonNull Animator animation) {
}
@Override
public void onAnimationCancel(@NonNull Animator animation) {
}
@Override
public void onAnimationRepeat(@NonNull Animator animation) {
}
});
lottie属性改变
如果想改变动画文件的填充颜色、不透明度、描边宽度等等内容,该怎么办呢,lottie提供了一个addValueCallback方法:
java
lottieAnimationView.addValueCallback(
new KeyPath("**"),
LottieProperty.COLOR,
new LottieValueCallback<Integer>(){
@Nullable
@Override
public Integer getValue(LottieFrameInfo frameInfo) {
return 0xffffff;
}
}
);
上图中的例子,主要目的是改变动画文件的颜色,
- 参数1,
keypath是指定要改变的范围,**表示改变所有图层的颜色(这里涉及到分析json文件的格式,就不细讲了,可以参考这篇博文 - 参数2,传入要改变的属性,例如:
STROKE_COLOR、OPACITY等等。具体可以点进这个类,查看支持哪些属性更改。 - 参数3,可以通过LottieFrameInfo具体到每一帧是否需要变化,如果不需要做任何处理,直接返回要修改的值即可,这里我对所有帧的颜色做更改。
2.3 LottieDrawable
重头戏!!!!
不知道大家有没有遇到一种情况:需要在自定义view里面实现lottie,这个时候需要在onDraw里面绘制LottieView
lottie官方也提供了可以用于任何view上的LottieDrawable,也是 LottieAnimationView的底层实现
java
public class MyLottieView extends View {
private LottieDrawable lottieDrawable;
private int mHeight;
private int mWidth;
private KeyPath keyPath;
private LottieValueCallback<Integer> lottieValueCallback;
public MyLottieView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
lottieDrawable = new LottieDrawable();
// 异步加载 Lottie JSON(推荐放 res/raw)
LottieCompositionFactory.fromRawRes(getContext(), R.raw.confor)
.addListener(comp -> {
setupComposition(comp, lottieDrawable);
})
.addFailureListener(t -> {
Log.e(TAG, "Lottie load error", t);
});
keyPath = new KeyPath("**");
lottieValueCallback = new LottieValueCallback<>(0xbb191970);
}
private void setupComposition(LottieComposition comp, LottieDrawable lottieDrawable) {
lottieDrawable.setCallback(this); // 必须:允许 Lottie 触发 invalidate()
lottieDrawable.setComposition(comp);
lottieDrawable.addAnimatorUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(@NonNull ValueAnimator animation) {
invalidate();
}
});
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mHeight = getMeasuredHeight();
mWidth = getMeasuredWidth();
}
@Override
protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
// 设置绘制区域
int width = getWidth();
//改变加载出来的动画颜色
drawable.addValueCallback(
keyPath,
LottieProperty.COLOR_FILTER,
lottieValueCallback
);
drawable.setBounds(0, 0, 64, 64);//指定绘制的大小
drawable.draw(canvas);
}
}
在自定义view里绘制lottieView还是比较复杂的,上面就是一个简单的例子,可以根据需求,做进一步改动。
下面简单来解析一下上面代码的流程:
- 首先是初始化一个
lottieDrawable,它继承自Drawable - 然后是异步加载json动画文件,这一步lottie内部做了异步处理,解析得到的内容是无状态的动画模型------
LottieComposition,我们需要在提供的回调内进行下一步处理 - 将解析得到的json文件加载到
lottieDrawable里,并且为lottieDrawable绑定drawable回调,因为我们是支持animattion的drawable。并且设置onAnimationUpdate回调,当动画运行时对每一帧进行绘制 - 最后就是绘制drawable到屏幕上,绘制方法和原生drawable一样,大家肯定比较熟悉。
!!坑
坑一
如果你的版本小于6.0.0,那么恭喜你,你可能在运行自己写的绘制代码后,lottie并未按照你设定的bounds显示,这是因为这前有bug导致left和top的设定是不生效的,在这个版本才被修复。所以最好用最新的版本,可以避免很多问题。

坑二
这个问题和json动画文件有关:
原因:因为动画里包含很多图层,每一层都涉及不透明度和颜色,所以如果你修改整个文件的不透明度,那可能会出现动画的镂空部分被加上不透明度,也就是原本透明的地方出现颜色。
这个问题的避免方式,只有在修改的时候自己确定好要修改哪些图层,这个就得了解你json文件的图层结构了。(咱哪有这么多时间来了解这些破结构啊,写个代码还要学你AE导出动画的格式?)
参考: