一、简介
Lottie
是 Airbnb
开源的一个面向 iOS、Android、React Native
的动画库,能分析 Adobe After Effects
导出的动画,并且能让原生 App
像使用静态素材一样使用这些动画,完美实现动画效果。
目前最新的版本是 3.2.2。
GitHub:https://github.com/airbnb/lottie-android
官方文档:http://airbnb.io/lottie/
优点
- 动画由设计使用专业的动画制作工具 Adobe After Effects 来实现,使动画实现更加方便,动画效果也更好;
- 前端可以方便的调用动画,并对动画进行控制,减少前端动画工作量;
- 设计制作动画,前端展现动画,专业人做专业事,分工合理;
- 卖家秀即买家秀,还原程度百分之百;
- 使用 lottie 方案,json 文件大小会比 gif 文件小很多,性能也会更好。
缺点
lottie-web
文件本身仍然比较大,lottie.js
大小为513k,轻量版压缩后也有144k,经过gzip后,大小为39k。所以,需要注意lottie-web的加载。目前H5项目有离线包,PC项目也会上PWA,会对其进行缓存,保证加载速度。lottie
动画其实可以理解为svg
动画/canvas
动画,不能给已存在的html
添加动画效果;- 动画
json
文件的导出,目前是将AE里面的参数一一导出成json内容,如果设计师建了很多的图层,可能仍然有json文件比较大(20kb)的问题。需要设计师遵循一定的规范。 - 有很少量的
AE
动画效果,lottie
无法实现,有些是因为性能问题,有些是没有做。比如:描边动画等
二、配置
1. 在 app/build.gradle 中添加如下:
implementation 'com.airbnb.android:lottie:3.2.2'
三、使用
1. 在 main/assets/data.json下添加动画资源 .
lottieAnimationView = findViewById(R.id.lottieAnimationView);
lottieAnimationView.setImageAssetsFolder("images");
lottieAnimationView.setAnimation("data.json");
lottieAnimationView.loop(true);
lottieAnimationView.playAnimation();
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/animation_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:lottie_fileName="data.json"
app:lottie_loop="true"
app:lottie_autoPlay="true"/>
2. Json String
加载服务器上的 .json 文件,若有图片可以设置本地代理文件夹或者将图片资源放入 JSON
。
private void loadUrl(String url) {
Request request = new Request.Builder().url(url).build();
OkHttpClient client = new OkHttpClient();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Call call, IOException e) {}
@Override public void onResponse(Call call, Response response) throws IOException {
try {
JSONObject json = new JSONObject(response.body().string());
LottieComposition.Factory
.fromJson(getResources(), json, new OnCompositionLoadedListener() {
@Override
public void onCompositionLoaded(LottieComposition composition) {
lottieAnimationView.setComposition(composition);
lottieAnimationView.playAnimation();
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
3. Url 服务器上的压缩包(包含 images 和 json 文件)
- 通过 url 直接加载
lottieAnimationView.setAnimationFromUrl(url);
lottieAnimationView.playAnimation();
- 下载到本地解压后指定文件夹代理
// 资源zip
public final static File LOTTIE_FILES = new File(Environment.getExternalStorageDirectory()+"/ctclient/lottie/lottie.zip");
// 动效图片资源
public final static File IMAGES_FILES = new File(Environment.getExternalStorageDirectory()+"/ctclient/lottie/images");
// data.json路径
public final static File JSON_FILE = new File(Environment.getExternalStorageDirectory()+"/ctclient/lottie/data.json");
FileInputStream fis = null;
if (JSON_FILE.exists()) {
try {
fis = new FileInputStream(JSON_FILE);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
if (fis == null || !IMAGES_FILES.exists()) {
Log.i("huangssh", "动画资源不存在");
return;
}
final String absolutePath = IMAGES_FILES.getAbsolutePath();
// 开启硬件加速
lottieAnimationView.useHardwareAcceleration(true);
// 设置动画文件夹代理类
lottieAnimationView.setImageAssetDelegate(new ImageAssetDelegate() {
@Override
public Bitmap fetchBitmap(LottieImageAsset asset) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inScaled = true;
opts.inDensity = UtilPhoneParam.densityDpi;
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeFile(absolutePath + File.separator + asset.getFileName(), opts);
}catch (Exception e){
e.printStackTrace();
}
return bitmap;
}
});
// 设置动画
LottieComposition.Factory.fromInputStream(fis, new OnCompositionLoadedListener() {
@Override
public void onCompositionLoaded(@Nullable LottieComposition composition) {
lottieAnimationView.setComposition(composition);
lottieAnimationView.playAnimation();
}
});
4. 加载 SDCard 字体
lottieAnimationView.setFontAssetDelegate(new FontAssetDelegate(){
public Typeface fetchFont(String fontFamily) {
Typeface customFont = Typeface.createFromFile(FONT_PATH + fontFamily);
return customFont;
}
});
四、常用方法
1. 监听动画进度 [0,1]
lottieAnimationView.addAnimatorUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
// 判断动画加载结束
if (valueAnimator.getAnimatedFraction() == 1f) {
if (dialog.isShowing() && getActivity() != null)
dialog.dismiss();
}
}
});
2. 暂停/取消/播放
lottieAnimationView.pauseAnimation();
lottieAnimationView.cancelAnimation();
lottieAnimationView.playAnimation();
3. 循环/播放某个部分
lottieAnimationView.loop(true);
4. 硬件加速,解决lottie卡顿问题
lottieAnimationView.useHardwareAcceleration(true);
5. 缓存
/*
* Lottie内部有两个缓存map(强引用缓存,弱引用缓存),在动画文件加载完成后会根据设置的缓存策略缓存动画,方便下次使用。
*/
lottieAnimationView.setAnimation(animation, LottieAnimationView.CacheStrategy.Strong); //强缓存
lottieAnimationView.setAnimation(animation, LottieAnimationView.CacheStrategy.Weak); //弱缓存