Android刷新框架和刷新动画

需求确定

日常开发中,页面刷新是一个非常常见的功能,各种优秀的框架也是非常多,功能也是大同小异,于是刷新过程中的动画就成了差异化的最好实现方式。所以,现在需要在刷新框架的基础上重新定义应用专属的动画。

实现思路

很难说每一个三方的刷新框架都有开放自定义加载动画的功能,自己写的又鉴于个人能力和精力上面的不足,很难尽善尽美,但是就目前我个人一直使用的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);
            }
        });
    }

}

大功告成,可以向产品露出慈父般的微笑了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值