zoukankan      html  css  js  c++  java
  • RecyclerView下拉刷新和上拉加载更多实现

    RecyclerView下拉刷新和上拉加载更多实现

    转 https://www.jianshu.com/p/4ea7c2d95ecf

     

    在Android开发中,RecyclerView算是使用频率非常广泛的组件了吧,在这里对RecyclerView比较常用的下拉刷新和上拉加载更多的功能实现做个记录,方便以后查看。
    在这里下拉刷新使用的是官方提供的SwipeRefreshLayout,然后上拉加载更多的功能使用的是第三方库BaseRecyclerViewAdapterHelper实现。

    依赖导入

    在项目build.gradle文件中添加以下代码导入依赖:

    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.46'
    implementation group: 'androidx.recyclerview', name: 'recyclerview', version: '1.1.0-alpha01'
    
    下拉刷新和上拉加载更多实现
    • 实体类UserData
    public class UserData {
        private String userName;
    
        public UserData() {
        }
    
        public UserData(String userName) {
            this.userName = userName;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    }
    
    • RecyclerView对应的Adapter
    import android.graphics.Color;
    
    import com.chad.library.adapter.base.BaseQuickAdapter;
    import com.chad.library.adapter.base.BaseViewHolder;
    
    import java.util.List;
    
    import androidx.annotation.Nullable;
    
    public class MainAdapter extends BaseQuickAdapter<UserData, BaseViewHolder> {
        public MainAdapter(int layoutResId, @Nullable List<UserData> data) {
            super(layoutResId, data);
        }
    
        @Override
        protected void convert(BaseViewHolder helper, UserData item) {
            int adapterPosition = helper.getAdapterPosition();
            if (adapterPosition % 2 == 0) {
                helper.setBackgroundColor(R.id.rlContent, Color.RED);
            }else {
                helper.setBackgroundColor(R.id.rlContent, Color.YELLOW);
            }
            helper.setText(R.id.tvName, item.getUserName());
        }
    }
    
    • RecyclerView对应的Adapter布局文件recycler_item_demo.xml
    <?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="wrap_content"
        android:id="@+id/rlContent"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/tvName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:padding="20dp"
            android:text="测试"
            android:textColor="#333333"
            android:textSize="30dp" />
    
    </RelativeLayout>
    
    • MainActivity
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.SystemClock;
    import android.util.Log;
    import android.view.View;
    
    import com.chad.library.adapter.base.BaseQuickAdapter;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {
    
        private SwipeRefreshLayout swipeRefreshLayout;
        private RecyclerView recyclerView;
    
        private List<UserData> userDatas = new ArrayList<>();
        private int count = 0;
        private int loadMoreCount = 0;
        private MainAdapter mainAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
            recyclerView = findViewById(R.id.recyclerView);
    
            LinearLayoutManager layoutManager = new LinearLayoutManager(this);
            recyclerView.setLayoutManager(layoutManager);
            mainAdapter = new MainAdapter(R.layout.recycler_item_demo, userDatas);
            mainAdapter.setLoadMoreView(new CustomLoadMoreView());
            //设置RecyclerView条目点击事件
            mainAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
                @Override
                public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                    UserData item = mainAdapter.getItem(position);
                    Log.e(MainActivity.this.getClass().getSimpleName(), "点击条目: " + position + "----userName: " + item.getUserName());
                }
            });
            mainAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
                @Override
                public void onLoadMoreRequested() {
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            List<UserData> userDataList = getDatas(false);
    
                            if (loadMoreCount == 1) {
                                //正常加载更多,还有下一页
                                mainAdapter.addData(userDataList);
                                mainAdapter.loadMoreComplete();
                            } else if (loadMoreCount == 2) {
                                //返回加载失败
                                mainAdapter.loadMoreFail();
                            } else if (loadMoreCount == 3) {
                                //加载到最后
                                mainAdapter.addData(userDataList.subList(0, 6));
                                mainAdapter.loadMoreEnd();
                            }
                        }
                    }, 3000);
                }
            }, recyclerView);
            recyclerView.setAdapter(mainAdapter);
    
            swipeRefreshLayout.setOnRefreshListener(this);
            onRefresh();
        }
    
        private List<UserData> getDatas(boolean isRefresh) {
            if (isRefresh) {
                count = 0;
            }
    
            List<UserData> dataList = new ArrayList<>();
            for (int i = count; i < count + 10; i++) {
                if (isRefresh) {
                    loadMoreCount = 0;
                    dataList.add(new UserData("下拉刷新数据" + i));
                } else {
                    dataList.add(new UserData("上拉加载更多数据" + i));
                }
            }
    
            if (!isRefresh) {
                loadMoreCount++;
            }
    
            count += 10;
    
            return dataList;
        }
    
        @Override
        public void onRefresh() {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    List<UserData> userDataList = getDatas(true);
                    mainAdapter.setNewData(userDataList);
                    mainAdapter.loadMoreComplete();
                    swipeRefreshLayout.setRefreshing(false);
                }
            }, 3000);
        }
    }
    

    以上代码中RecyclerView的数据集使用假数据测试,并且模拟第一次上拉加载更多成功,第二次上拉加载失败,点击失败重试,最后加载完毕(即没有更多数据)

    • MainActivity的布局文件activity_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
            android:id="@+id/swipeRefreshLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
    
        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    
    • 运行结果截图


       
      运行结果
    注意事项

    加载更多的View布局是可以自定义的,自定义调用的方法:

    mainAdapter.setLoadMoreView(new CustomLoadMoreView());
    
    • CustomLoadMoreView
    import com.chad.library.adapter.base.loadmore.LoadMoreView;
    public final class CustomLoadMoreView extends LoadMoreView {
    
        @Override
        public int getLayoutId() {
            return R.layout.view_load_more;
        }
    
        @Override
        protected int getLoadingViewId() {
            return R.id.load_more_loading_view;
        }
    
        @Override
        protected int getLoadFailViewId() {
            return R.id.load_more_load_fail_view;
        }
    
        @Override
        protected int getLoadEndViewId() {
            return R.id.load_more_load_end_view;
        }
    }
    
    • 加载更多布局文件view_load_more.xml
    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40">
    
        <LinearLayout
            android:id="@+id/load_more_loading_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:visibility="visible"
            android:orientation="horizontal">
    
            <ProgressBar
                android:id="@+id/pb_footer"
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:layout_marginLeft="16dp"
                android:layout_marginRight="16dp" />
    
            <TextView
                android:id="@+id/tv_footer"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="正在加载中..." />
        </LinearLayout>
    
        <FrameLayout
            android:id="@+id/load_more_load_fail_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone">
    
    
            <TextView
                android:id="@+id/tv_prompt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="@string/brvah_load_failed"/>
    
        </FrameLayout>
    
        <FrameLayout
            android:id="@+id/load_more_load_end_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="@string/brvah_load_end"
                android:textColor="@android:color/darker_gray"/>
        </FrameLayout>
    </FrameLayout>
    

    BaseRecyclerViewAdapterHelper的功能不仅仅于此,后续再继续补充。

  • 相关阅读:
    sqlserver获取当前id的前一条数据和后一条数据
    C#实现测量程序运行时间及cpu使用时间
    类库dll引用不成功问题
    合并相同字段
    Android之来历
    XML and JSON 验证
    特殊符号
    git 使用
    格式化字符串:金额
    grunt + sass 使用记录
  • 原文地址:https://www.cnblogs.com/it-tsz/p/11372187.html
Copyright © 2011-2022 走看看