需求确定
日常开发中,页面刷新是一个非常常见的功能,各种优秀的框架也是非常多,功能也是大同小异,于是刷新过程中的动画就成了差异化的最好实现方式。所以,现在需要在刷新框架的基础上重新定义应用专属的动画。
实现思路
很难说每一个三方的刷新框架都有开放自定义加载动画的功能,自己写的又鉴于个人能力和精力上面的不足,很难尽善尽美,但是就目前我个人一直使用的SmartRefreshLayout来说,是可以的。剩下的就是动画定制了,很多复杂的动画多数都是使用的逐帧动画,Lottie这个贼优秀的动画框架就显得非常有用。所以本次的实现思路是SmartRefreshLayout+Lottie实现定制刷新框架。
实现
依赖:
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-andx-15'
implementation 'com.airbnb.android:lottie:3.0.7'
可能导入的过程中会出现androidX的问题,需要在gradle.properties加入
android.useAndroidX=true
android.enableJetifier=true
正式开始:
1.header_refresh.xml(绘制刷新头部)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center_vertical"
android:orientation="vertical">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/loading_lottie"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
app:lottie_fileName="refresh.json"
app:lottie_loop="true" />
</LinearLayout>
2.实现自定义刷新头部RefreshLottieHeader
public class RefreshLottieHeader extends LinearLayout implements RefreshHeader {
/**
* The M animation view.
*/
LottieAnimationView mAnimationView;
/**
* Instantiates a new My refresh lottie header.
*
* @param context the context
*/
public RefreshLottieHeader(Context context) {
super(context);
initView(context);
}
/**
* 注意不能为null
*
* @return
*/
@NonNull
@Override
public View getView() {
return this;
}
@Override
public SpinnerStyle getSpinnerStyle() {
return SpinnerStyle.Translate;
}
@Override
public void setPrimaryColors(int... colors) {
}
@Override
public void onInitialized(RefreshKernel kernel, int height, int extendHeight) {
}
@Override
public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) {
if (mAnimationView.getProgress() != 0 && isDragging) {
mAnimationView.setProgress(0);
}
}
@Override
public void onReleased(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) {
}
@Override
public void onHorizontalDrag(float percentX, int offsetX, int offsetMax) {
}
@Override
public void onStartAnimator(RefreshLayout layout, int height, int extendHeight) {
mAnimationView.playAnimation();
}
@Override
public int onFinish(RefreshLayout layout, boolean success) {
mAnimationView.cancelAnimation();
return 0;
}
@Override
public boolean isSupportHorizontalDrag() {
return false;
}
@Override
public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) {
}
private void initView(Context context) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.header_refresh, this);
mAnimationView = (LottieAnimationView) view.findViewById(R.id.loading_lottie);
}
/**
* Set animation view json.
*
* @param animName json文件名
*/
public void setAnimationViewJson(String animName) {
mAnimationView.setAnimation(animName);
}
/**
* Set animation view json.
*
* @param anim the anim
*/
public void setAnimationViewJson(Animation anim) {
mAnimationView.setAnimation(anim);
}
}
剩下的就是调用SmartRefreshLayout.setRefreshHeader(new RefreshLottieHeader(this))方法设定进去。
下面是简单的使用例子:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<com.scwang.smartrefresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/srl_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_activity_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Hello World!"
android:textSize="30dp" />
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
MainActivity
public class MainActivity extends AppCompatActivity {
private SmartRefreshLayout mSrl;
private RefreshLottieHeader mHeader;
private TextView mTvContent;
private int position = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSrl = findViewById(R.id.srl_content);
mTvContent = findViewById(R.id.tv_activity_content);
mHeader = new RefreshLottieHeader(this);
mSrl.setRefreshHeader(mHeader);
mSrl.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(@NonNull RefreshLayout refreshLayout) {
mSrl.getLayout().postDelayed(new Runnable() {
@Override
public void run() {
mTvContent.setText(String.valueOf(position++));
mSrl.finishRefresh();
}
}, 2000);
}
});
}
}
大功告成,可以向产品露出慈父般的微笑了!