Lottie - 动画的使用
作者:互联网
一、前言:
Lottie 是Airbnb开源的一个面向 iOS、Android、React Native 的动画库,能分析 Adobe After Effects 导出的动画,并且能让原生 App 像使用静态素材一样使用这些动画,完美实现动画效果。
现在使用各平台的 native 代码实现一套复杂的动画是一件很困难并且耗时的事,我们需要为不同尺寸的屏幕加载不同的素材资源,还需要写大量难维护的代码,而Lottie可以做到同一个动画文件在不同平台上实现相同的效果,极大减少开发时间,实现不同的动画,只需要设置不同的动画文件即可,极大减少开发和维护成本。
Lottie 地址:https://github.com/airbnb/lottie-android
Lottie 官网:https://airbnb.design/lottie/
1、为什么使用Lottie?
跨平台只有制作一套json动画文件便可以跨平台在 Android ios ReactNeative上使用,lottie库负责解析json文件并播放动画
可以支持网络下载json文件,本地播放,实时更新动画资源。
运行时效率上仅仅用Canvas去draw而已,流畅度非常棒,所以哪怕在Listview里去大量显示,内存占用和绘图效率都远远高于帧动画。
实现效果可以按设计出的100%还原到产品中。
开发周期大大减少。
二、使用:
1、在项目 的 build.gradle 文件添加依赖
dependencies {
//lottie框架(现在的最新版本)
implementation'com.airbnb.android:lottie:3.4.1'
}
注意:版本过老,会报错
2、 添加 Adobe After Effects 导出的动画文件
Lottie默认读取Assets中的文件,我们需要把设计导出的动画文件.json 保存在app/src/main/assets文件里。
3、 使用Lottie
直接布局加载*.json文件的方法:
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/animation_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:lottie_fileName="app_loading.json"
app:lottie_loop="true" />
lottie_fileName表示本地Assets文件中存的json动画文件
lottie_loop表示动画循环执行
2、代码加载动画方法
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/animation_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:lottie_fileName="app_loading.json"
app:lottie_loop="true"
app:lottie_autoPlay="true" />
lottie_autoPlay表示设置是否自动启动播放
//声明控件
lottieAnimationView = findViewById(R.id.animation_view);
//这个可有可无,如果不涉及本地图片做动画可忽略
// lottieAnimationView.setImageAssetsFolder("images");
//设置动画文件
lottieAnimationView.setAnimation("app_loading.json");
//是否循环执行
lottieAnimationView.loop(true);
//执行动画
lottieAnimationView.playAnimation();
3、加载网络.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();
}
}
});
}
三、 常用方法
animationView.isAnimating(); 动画是否在播放
animationView.playAnimation(); 播放动画
animationView.pauseAnimation(); 暂停动画
animationView.cancelAnimation(); 取消动画
animationView.setProgress(progress); 设置进度,progress范围0~1
animationView.setMinAndMaxProgress(min,max); 设置播放范围,0~1
监听动画进度
设置动画硬件加速
缓存动画
Lottie本身在 Android 平台已经做了适配工作,而且适配原理很简单,解析时,从 读取宽高之后会再乘以手机的密度。再在使用的时候判断适配后的宽高是否超过屏幕的宽高,如果超过则再进行缩放。以此保障 Lottie 在 Android 平台的显示效果
四、自定义刷新头
public class CustomClassicsHeader extends LinearLayout implements RefreshHeader {
private TextView mHeaderText;//标题文本
// private ImageView mArrowView;//下拉箭头
// private ImageView mProgressView;//刷新动画视图
// private ProgressDrawable mProgressDrawable;//刷新动画
private LottieAnimationView lottieAnimationView;//加载动画
private View view;
public CustomClassicsHeader(Context context) {
this(context, null);
}
public CustomClassicsHeader(Context context, AttributeSet attrs) {
super(context, attrs, 0);
view = LayoutInflater.from(context).inflate(R.layout.item_custom_header, this);
// setGravity(Gravity.CENTER);
// mHeaderText = new TextView(context);
// mProgressDrawable = new ProgressDrawable();
mArrowView = new ImageView(context);
mProgressView = new ImageView(context);
// lottieAnimationView = new LottieAnimationView(context);
// //mProgressView.setImageDrawable(mProgressDrawable);
// //mArrowView.setImageDrawable(new ArrowDrawable());
//
// mHeaderText.setTextColor(context.getResources().getColor(R.color.color_FF333333));
addView(mProgressView, SmartUtil.dp2px(20), SmartUtil.dp2px(20));
addView(mArrowView, SmartUtil.dp2px(20), SmartUtil.dp2px(20));
// addView(lottieAnimationView, SmartUtil.dp2px(25), SmartUtil.dp2px(25));
// addView(new Space(context), SmartUtil.dp2px(20), SmartUtil.dp2px(20));
// addView(mHeaderText, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// setMinimumHeight(SmartUtil.dp2px(60));
// //加载动画
// lottieAnimationView.setAnimation("app_pull_refresh.json");
// //是否循环执行
// lottieAnimationView.loop(true);
lottieAnimationView = view.findViewById(R.id.lottieAnimationView);
mHeaderText = view.findViewById(R.id.tv_head);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
@NonNull
public View getView() {
return view;//真实的视图就是自己,不能返回null
}
@NonNull
@Override
public SpinnerStyle getSpinnerStyle() {
return SpinnerStyle.Translate;//指定为平移,不能null
}
@Override
public void onStartAnimator(@NonNull RefreshLayout layout, int height, int maxDragHeight) {
// mProgressDrawable.start();//开始动画
//执行动画
lottieAnimationView.playAnimation();
}
@Override
public int onFinish(@NonNull RefreshLayout layout, boolean success) {
// mProgressDrawable.stop();//停止动画
// mProgressView.setVisibility(GONE);//隐藏动画
lottieAnimationView.cancelAnimation();
if (success) {
mHeaderText.setText("刷新完成");
} else {
mHeaderText.setText("刷新失败");
}
return 500;//延迟500毫秒之后再弹回
}
@Override
public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) {
refreshLayout.setPrimaryColorsId(R.color.color_FFF96857,R.color.color_FFF96857);//全局设置主题颜色
switch (newState) {
case None:
case PullDownToRefresh:
mHeaderText.setText("下拉开始刷新");
// mArrowView.setVisibility(VISIBLE);//显示下拉箭头
// mProgressView.setVisibility(GONE);//隐藏动画
// mArrowView.animate().rotation(0);//还原箭头方向
break;
case Refreshing:
mHeaderText.setText("正在刷新");
// mProgressView.setVisibility(VISIBLE);//显示加载动画
// mArrowView.setVisibility(GONE);//隐藏箭头
break;
case ReleaseToRefresh:
mHeaderText.setText("释放立即刷新");
// mArrowView.animate().rotation(180);//显示箭头改为朝上
break;
}
}
@Override
public void setPrimaryColors(int... colors) {
}
@Override
public void onInitialized(@NonNull RefreshKernel kernel, int height, int maxDragHeight) {
}
/**
* 移动
* @param isDragging
* @param percent
* @param offset
* @param height
* @param maxDragHeight
*/
@Override
public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) {
if(isDragging){
//设置进度
lottieAnimationView.setProgress(percent);
}
}
@Override
public void onReleased(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) {
}
@Override
public void onHorizontalDrag(float percentX, int offsetX, int offsetMax) {
}
@Override
public boolean isSupportHorizontalDrag() {
return false;
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_70"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:background="@color/color_FFFFFF"
>
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottieAnimationView"
android:layout_width="@dimen/dp_35"
android:layout_height="@dimen/dp_35"
android:layout_marginTop="@dimen/dp_10"
app:lottie_fileName="app_pull_refresh.json"
app:lottie_loop="true"
app:lottie_autoPlay="true"
android:layout_centerHorizontal="true"
/>
<TextView
android:id="@+id/tv_head"
android:layout_marginTop="@dimen/dp_3"
android:layout_below="@+id/lottieAnimationView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_FFA9A9A9"
android:textSize="@dimen/sp_11"
android:layout_centerHorizontal="true"
android:text="下拉开始刷新"
/>
</RelativeLayout>
标签:动画,int,void,lottieAnimationView,使用,Override,Lottie,public 来源: https://blog.csdn.net/weixin_42803953/article/details/112803817