Android 敏捷开发助手
博客创建时间:2021.04.24
博客更新时间:2023.01.28
以Android studio build=7.0.0,SDKVersion 31来分析讲解。如图文和网上其他资料不一致,可能是别的资料版本较低而已。
Android开发中,常规的动画特效有:
UI常常会用到一些动画特效,比如心形跳动、返回效果等,此时常规手段往往力不从心,使用Lottie就能助力你飞起来。
Lottie是一个为Android和iOS设备提供的一个开源框架,它能够解析通过Adobe After Effects 软件做出来的动画,动画文件通过Bodymovin导出json文件,然后由Lottie中的LottieAnimationView解析json渲染动画。 (如上图)
Lottie支持多平台,使用同一个JSON动画文件,可在不同平台实现相同的效果。Android 通过Airbnb的开源项目lottie-android实现,最低支持 API 16。
Lottie Github地址:https://github.com/airbnb/lottie-android
Lottie材料网站:https://lottiefiles.com/
优点:
由于将动画变成了json字符串,相比几M体积的gif图,等质量下的压缩率达到80%及以上。
支持云端动画资源加载,上线新的动画效果不需要发版
支持实时渲染 After Effects 动画,让 app 加载动画像加载图片一样简单。
因为Lottie是利用json文件生成动画,从而避免了不同分辨率、不同设备尺寸上面动画效果存在差异的问题。
只需要进行一动画绘制,生成一次json文件,跨端使用(android、ios、web)
Android: API16+
IOS : IOS8+ /MacOS 10.10+
WEB:调用Bodymovin提供的js库 — bodymovin.js
拿到动画.json文件后,研发可以灵活的自行修复动画的颜色、路径等数据,自行扩展
拥有完整丰富的API,除了常规的播放、控制进度、暂停控制,还可以缓存、添加额外的原生UI
在未开启硬件加速的情况下,帧率、内存,CPU都比属性动画差,开启硬件加速后,性能差不多。
缺点:
Lottie尚不支持效果菜单中的表达式或任何效果。
使用alpha遮罩会影响性能。 如果你使用的是alpha遮罩或alpha倒置遮罩,遮罩的大小会对性能产生更大的影响。
Lottie还不支持阴影,颜色叠加或笔触等图层效果。
导出比您想要支持的最宽屏幕更宽的动画,使开发者在Android上使用centerCrop类型或在iOS上使用aspectFill内容模式。
依赖配置如下
implementation 'com.airbnb.android:lottie:2.7.0'
implementation 'com.airbnb.android:lottie:$lottieVersion'
@SuppressLint("ResourceType")
private void initView() {
LottieAnimationView animationView = (LottieAnimationView) findViewById(R.id.lottieAnimationView);
// 设定 asssets文件目录
// lottieAnimationView.setImageAssetsFolder("images");
// 在assets目录下的动画json文件名。
// animationView.setAnimation("face.json");
animationView.setImageResource(R.raw.face);
// animationView.setAnimationFromUrl("https://lottiefiles.com/60170-search");
// 开启硬件加速
lottieAnimationView.useHardwareAcceleration(true);
//设置动画循环播放
animationView.loop(true);
//assets目录下的子目录,存放动画所需的图片
// animationView.setImageAssetsFolder("images/");
animationView.playAnimation();//播放动画
}
部分参数可以直接在xml 控件中使用
<!-- xml配置使用 -->
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottieAnimationView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:lottie_fileName="hello-world.json"
app:lottie_loop="true"
app:lottie_rawRes="@raw/heart"
app:lottie_imageAssetsFolder="images"
app:lottie_autoPlay="true"/>
lottie_fileName
:在app/src/main/assets目录下的动画,以json文件名。
lottie_rawRes
:存放在app/src/main/res/raw 目录下的json动画
app:lottie_rawRes,app:lottie_fileName这两个属性基本相似。
lottie_loop
:动画是否循环播放,默认不循环播放。
lottie_autoPlay
:动画是否自动播放,默认不自动播放。
lottie_imageAssetsFolder
:动画所依赖的图片目录,在app/src/main/assets/目录下的子目录,该子目录存放所有图片。
lottie_colorFilter
:设置动画的着色颜色
lottie_repeatCount
:重复次数,当你设置-1的时候就代表相应的循环了!
lottie_scale
:设置动画的比例
lottie_repeatMode
: 设置动画的重复模式RESTART:重复、REVERSE:反向
1. 资源加载
动画文件加载有三种方式
1.加载main/assets目录下的动画
// 1.代码调用
animationView.setImageAssetsFolder("test.json");
// 或者 xml调用
app:lottie_fileName="test.json"
app:lottie_rawRes="@raw/face"
3.加载Url
注意url指向的内容需要时json格式的数据
java animationView.setAnimationFromUrl("https://lottiefiles.com/60170-search");
2. 基本操作
// 动画是否正在运行
animationView.isAnimating()
// progress范围0~1f,设置动画进度
animationView.setProgress(0.5f);
//播放动画
animationView.playAnimation();
//取消动画
animationView.cancelAnimation();
// 暂停动画
lottieAnimationView.pauseAnimation();
//重启动画
animationView.resumeAnimation();
//设置X轴方向上的缩放比例,0f为不可见,1f原始大小 Ps.原setScale方法在2.0.0版本后已弃用
animationView.setScaleX(0.5f);
//设置Y轴方向上的缩放比例
animationView.setScaleY(0.5f);
setMinFrame(...)
setMaxFrame(...)
setMinProgress(...)
setMaxProgress(...)
setMinAndMaxFrame(...)
setMinAndMaxProgress(...)
animationView.setProgress(0.5f);//手动设置动画进度
// Custom animation speed or duration.
ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f)//自定义一个属性动画
.setDuration(500);
3. 动作监听
// json文件加载完成监听
animationView.addLottieOnCompositionLoadedListener { }
//监听动画播放进度 [0,1]
lottieAnimationView.addAnimatorUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
// 判断动画加载结束
if (valueAnimator.getAnimatedFraction() == 1f) {
if (dialog.isShowing() && getActivity() != null)
dialog.dismiss();
}
});
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
animationView.setProgress(animation.getAnimatedValue());
}
});
animator.start();
4. 设置动画文件夹代理
// 设置动画文件夹代理类
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;
}
});
5. 加载SDCard字体
lottieAnimationView.setFontAssetDelegate(new FontAssetDelegate(){
public Typeface fetchFont(String fontFamily) {
Typeface customFont = Typeface.createFromFile(FONT_PATH + fontFamily);
return customFont;
}
});
6. 缓存设置
/*
* Lottie内部有两个缓存map(强引用缓存,弱引用缓存),在动画文件加载完成后会根据设置的缓存策略缓存动画,方便下次使用。
*/
lottieAnimationView.setAnimation(animation, LottieAnimationView.CacheStrategy.Strong); //强缓存
lottieAnimationView.setAnimation(animation, LottieAnimationView.CacheStrategy.Weak); //弱缓存
LottieAnimationView.CacheStrategy.None); //默认
lottieAnimationView.setProgress(progress); //设置当前进度
lottieAnimationView.buildDrawingCache(); //强制缓存绘制数据
Bitmap image = lottieAnimationView.getDrawingCache(); //获取当前绘制数据
在列表中使用动画,推荐使用缓存,避免内存抖动。
7. 显示效果定义
// 任何符合颜色过滤界面的类
final PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.LIGHTEN);
// 在整个视图中添加一个颜色过滤器
animationView.addColorFilter(colorFilter);
//在特定的图层中添加一个颜色滤镜
animationView.addColorFilterToLayer("hello_layer", colorFilter);
// 添加一个彩色过滤器特效“hello_layer”上的内容
animationView.addColorFilterToContent("hello_layer", "hello", colorFilter);
// 清除所有的颜色滤镜
// 颜色过滤器只适用于图层,如图像层和实体层,以及包含填充、描边或组内容的内容。
animationView.clearColorFilters();
LottieDrawable会分出很多图层,然后用图层管理者 CompositionLayers去分别进行绘制。
绘制的时候根据时间,计算每个时间点的 关键帧。这个时候用到了我们在属性动画所学过的 KeyFrame 关键帧处理类。
Android端的实现是基于Drawable,IOS端是基于Layer,最终都是对canvas的操作。原理实质是使用各平台的 核心 Animation 的API进行动画的绘制和渲染。
Lottie动画对于UI要求较高的项目是个非常必要的选择,使用普通动画无法实现的效果,使用Lottie能轻松达到。
自己写的案例demo,供大家一看Lottie源码。
相关链接:
扩展链接:
扩展训练:
博客书写不易,您的点赞收藏是我前进的动力,千万别忘记点赞、 收藏 ^ _ ^ !