smartrefresh实现下拉刷新和加载更多

背景

项目中,使用了smartrefresh实现了recyclerview的下拉刷新和加载更多功能,简单总结一波,持续完善。

基本使用

1、添加依赖

// 下拉刷新,上拉加载
    implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.3'
    // 没有使用特殊Header,可以不加这一依赖
    implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.3'

2、xml布局中使用

image.png

<?xml version="1.0" encoding="utf-8"?>
<com.scwang.smartrefresh.layout.SmartRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/refreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/ball"/>
</com.scwang.smartrefresh.layout.SmartRefreshLayout>

3、activity中使用

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_smart_refresh_layout);

        mRefreshLayout = findViewById(R.id.refreshLayout);
//        mRefreshLayout.setRefreshHeader(new MyRefreshAnimHeader(this));
        // 下拉刷新
        mRefreshLayout.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(RefreshLayout refreshlayout) {
                // 传入false表示刷新失败
                refreshlayout.finishRefresh(2000/*,false*/);
            }
        });

        // 上拉加载更多
        mRefreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore(RefreshLayout refreshlayout) {
                // 传入false表示加载失败
                refreshlayout.finishLoadMore(2000/*,false*/);
            }
        });
    }

smartrefresh结合lottie实现切换下拉刷新动画

添加依赖,在上面依赖的基础上新增

// 使用lottie
    implementation 'com.airbnb.android:lottie:2.2.0'

自定义RefreshHeader

public class MyRefreshAnimHeader extends LinearLayout implements RefreshHeader {
    LottieAnimationView mAnimationView;

    public MyRefreshAnimHeader(Context context) {
        super(context);
        initView(context);
    }

    public MyRefreshAnimHeader(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public MyRefreshAnimHeader(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    public MyRefreshAnimHeader(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView(context);
    }


    @NonNull
    @Override
    public View getView() {
        return this;
    }

    // 初始化View
    private void initView(Context context) {
        LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = layoutInflater.inflate(R.layout.loading_lottie, this);
        // 使用自定义的xml布局文件
        mAnimationView = (LottieAnimationView) view.findViewById(R.id.loading_lottie);
    }

    @NonNull
    @Override
    public SpinnerStyle getSpinnerStyle() {
        return SpinnerStyle.Translate;
    }

    @SuppressLint("RestrictedApi")
    @Override
    public void setPrimaryColors(int... colors) {

    }

    @SuppressLint("RestrictedApi")
    @Override
    public void onInitialized(@NonNull RefreshKernel kernel, int height, int maxDragHeight) {

    }

    @SuppressLint("RestrictedApi")
    @Override
    public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) {

    }

    @SuppressLint("RestrictedApi")
    @Override
    public void onReleased(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) {

    }

    @SuppressLint("RestrictedApi")
    @Override
    public void onStartAnimator(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) {
        mAnimationView.playAnimation();
    }

    @SuppressLint("RestrictedApi")
    @Override
    public int onFinish(@NonNull RefreshLayout refreshLayout, boolean success) {
        mAnimationView.cancelAnimation();
        return 0;
    }

    @SuppressLint("RestrictedApi")
    @Override
    public void onHorizontalDrag(float percentX, int offsetX, int offsetMax) {

    }

    @Override
    public boolean isSupportHorizontalDrag() {
        return false;
    }

    @SuppressLint("RestrictedApi")
    @Override
    public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) {

    }

    public void setAnimationViewJson(String animName){
        mAnimationView.setAnimation(animName);
    }

    public void setAnimationViewJson(Animation anim){
        mAnimationView.setAnimation(anim);
    }
}

上面的基础demo中smartrefresh设置自定义的Header

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_smart_refresh_layout);

        mRefreshLayout = findViewById(R.id.refreshLayout);
        // 设置自定义header
        mRefreshLayout.setRefreshHeader(new MyRefreshAnimHeader(this));
        // 下拉刷新
        mRefreshLayout.setOnRefreshListener(refreshlayout -> {
            // 传入false表示刷新失败
            refreshlayout.finishRefresh(2000/*,false*/);
        });

        // 上拉加载更多
        mRefreshLayout.setOnLoadMoreListener(refreshlayout -> {
            // 传入false表示加载失败
            refreshlayout.finishLoadMore(2000/*,false*/);
        });
    }

动画 Json 文件需要放在 main 目录的 assets 中

image.png 自定义布局文件使用我们的动画json文件 image.png loading_lottie.xml

<?xml version="1.0" encoding="utf-8"?>
<com.airbnb.lottie.LottieAnimationView android:id="@+id/loading_lottie"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    app:lottie_fileName="anim3.json"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" />