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的功能不仅仅于此,后续再继续补充。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM