Android——RecyclerView自定义OnScrollListener实现下拉刷新监听,上拉加载更多功能
【前言】
针对RecyclerView有很多开源的框架可以直接拿来用,比较有代表性的是BaseRecyclerViewAdapterHelper,功能很强大,具备上拉监听的功能。使用开源的东西固然省时省力,但是前期自定义的Adapter使用较多,不想再更改了,且总使用开源的东西慢慢人都变傻了,这个功能不算复杂,就自己查找相关资料参照实现了。
1、OnScrollListener滑动事件监听抽象类
这个抽象类是我们要实现下拉刷新,上拉加载的关键,其中有onScrollStateChanged 、onScrolled两个方法
- onScrollStateChanged:滑动状态改变时方法会被调用,第一个参数recyclerView是当前的列表,第二个参数newState是滑动状态(SCROLL_STATE_IDLE为无滑动,SCROLL_STATE_SETTLING为滑动中);
- onScrolled:滑动状态改变时方法会被调用,第一个参数recyclerView是当前的列表,xy为水平、垂直方向滑动坐标值,所以垂直方向,当y值>0时,说明列表正在向上滑动,<=0时列表向下滑动或停止。
/**
* An OnScrollListener can be added to a RecyclerView to receive messages when a scrolling event
* has occurred on that RecyclerView.
* <p>
* @see RecyclerView#addOnScrollListener(OnScrollListener)
* @see RecyclerView#clearOnChildAttachStateChangeListeners()
*
*/
public abstract static class OnScrollListener {
/**
* Callback method to be invoked when RecyclerView's scroll state changes.
*
* @param recyclerView The RecyclerView whose scroll state has changed.
* @param newState The updated scroll state. One of {@link #SCROLL_STATE_IDLE},
* {@link #SCROLL_STATE_DRAGGING} or {@link #SCROLL_STATE_SETTLING}.
*/
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState){}
/**
* Callback method to be invoked when the RecyclerView has been scrolled. This will be
* called after the scroll has completed.
* <p>
* This callback will also be called if visible item range changes after a layout
* calculation. In that case, dx and dy will be 0.
*
* @param recyclerView The RecyclerView which scrolled.
* @param dx The amount of horizontal scroll.
* @param dy The amount of vertical scroll.
*/
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){}
}
2、利用onScrollStateChanged及onScrolled方法实现下拉刷新及上拉加载更多
结合以上对两个方法及参数的说明,可知,结合这两个方法可判断出当前是下滑还是上滑动作,覆写方法,结合加入可视区域第一条和最后一条item的位置,可以判断出下拉、上拉的动作,因此完全可以自定义RecyclerView.OnScrollListener实现,关键思路:
- 下拉:可视区域第一条item位置==0 && 非上滑动作;
- 上拉:可视区域最后条item位置==列表item总数-1 && 上滑动作;
- 接口:定义回调接口,内部定义下拉刷新,及上拉加载更多两个方法,外部调用时覆写两个方式实现自己的业务逻辑。
完整的自定义RecyclerView.OnScrollListener代码如下:
public class RecyclerViewOnScrollListener extends RecyclerView.OnScrollListener {
//监听回调
private UpPullOnScrollListener listener;
public RecyclerViewOnScrollListener(UpPullOnScrollListener listener) {
this.listener = listener;
}
boolean isUpScroll = false; //是否正在上滑标记
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (newState == RecyclerView.SCROLL_STATE_IDLE) { //当前未滑动
int itemCount = manager.getItemCount(); //总数
int lastItemPosition = manager.findLastCompletelyVisibleItemPosition();//最后显示的位置
if (lastItemPosition == (itemCount - 1) && isUpScroll) {
listener.onLoadMore();
}
int fristItemPosition = manager.findFirstCompletelyVisibleItemPosition();//第一个显示的位置
if (fristItemPosition == (0) && !isUpScroll){
listener.onRefresh();
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// 大于0表示正在向上滑动,小于等于0表示停止或向下滑动
isUpScroll = dy > 0;
}
public interface UpPullOnScrollListener {
public void onLoadMore() ; //上拉加载更多的方法
public void onRefresh() ; //下拉刷新的方法
}
}
3、使用方法
1)RecyclerView的 public void addOnScrollListener(@NonNull OnScrollListener listener) 方法实现列表滑动事件的监听,传入的对象为OnScrollListener;
2)用自定义的RecyclerView.OnScrollListener写一个自己业务处理的监听器,eg:
private RecyclerViewOnScrollListener.UpPullOnScrollListener onScrollListener = new RecyclerViewOnScrollListener.UpPullOnScrollListener() {
@Override
public void onLoadMore() { //上拉处理逻辑
}
@Override
public void onRefresh() { //下拉刷新不在此处处理,使用的swipeRefreshLayout实现
}
};
3)调用监听即可:recyclerView.addOnScrollListener(new RecyclerViewOnScrollListener(onScrollListener));
4、利用SwipeRefreshLayout实现下拉刷新效果
用这个layout实现的下拉刷新效果更好看一些,而且也很方便,此处只写注意要点:
1)布局时 SwipeRefreshLayout 包裹 RecyclerView;
2)所在类实现SwipeRefreshLayout.OnRefreshListener接口;
3)SwipeRefreshLayout实例化对象设置刷新监听setOnRefreshListener(this);
4)覆写public void onRefresh()方法,其中写自己的刷新业务逻辑。
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 算法工程师-SQL进阶:神奇的自连接与子查询
- 算法工程师-SQL进阶:温柔的陷阱-NULL
- SpringBoot 异步任务处理
- SpringBoot整合 ActiveMQ快速入门 实现点对点推送
- Tomcat部署SpringBoot war包
- Vue之插槽Slot理解
- Docker六脉神剑 (三) 编写Dockerfile构建nginx镜像并推送到远程仓库给其他人使用
- 快速学习UML类图查看
- 设计模式 | 抽象工厂模式
- 设计模式 | 单例模式
- macOS 安装软件已损坏无法打开解决办法 (真好用!)
- nginx 配置反向代理
- ES6新特性速查表
- React-Native Android打包
- React-Native iOS打包