为RecyclerView添加下拉刷新功能
2023-04-18 16:49:15 时间
前言
在之前的文章中,我们实现了带有header和footer功能的WrapRecyclerView:实现一个带有header和footer功能的RecyclerView
现今App中列表的下拉刷新和上拉加载已经是一种习惯了,这两个操作也确实方便很多。
为RecyclerView添加这个功能可以通过多种方法,这里我选用了一种简单的做法。基于pulltorefresh这个库。
com.loopeer.android.thirdparty:pulltorefresh:<版本>
代码
首先要为WrapRecyclerView添加两个方法,如下:
public int getFirstVisiblePosition(){
int firstPosition = 0;
LayoutManager layoutManager = getLayoutManager();
if(layoutManager instanceof LinearLayoutManager){
firstPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
}
if(layoutManager instanceof GridLayoutManager){
firstPosition = ((GridLayoutManager) layoutManager).findFirstVisibleItemPosition();
}
if(layoutManager instanceof StaggeredGridLayoutManager){
int[] positions = ((StaggeredGridLayoutManager) layoutManager).findFirstVisibleItemPositions(null);
firstPosition = positions[0];
}
return firstPosition;
}
public int getLastVisiblePosition(){
int lastPosition = 0;
LayoutManager layoutManager = getLayoutManager();
if(layoutManager instanceof LinearLayoutManager){
lastPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
}
if(layoutManager instanceof GridLayoutManager){
lastPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
}
if(layoutManager instanceof StaggeredGridLayoutManager){
int[] positions = ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(null);
lastPosition = positions[positions.length - 1];
}
return lastPosition;
}
这两个方法用于辅助判断滑动时是否到顶或到底,下面会用到。注意对于不同的LayoutManager使用不同的方式来获取。
新建一个PullToRefreshRecyclerView,继承PullToRefreshBase
public class PullToRefreshRecyclerView extends PullToRefreshBase<WrapRecyclerView>{
需要重写几个方法来实现功能,如
@Override
protected boolean isReadyForPullEnd() {
int lastPosition = getRefreshableView().getLastVisiblePosition();
RecyclerView.LayoutManager layoutManager = getRefreshableView().getLayoutManager();
View lastView = layoutManager.findViewByPosition(lastPosition);
if(lastView != null) {
int lastBottom = lastView.getBottom();
return lastPosition == getRefreshableView().getRealItemCount() - 1 && lastBottom <= getRefreshableView().getBottom();
}
else{
return true;
}
}
@Override
protected boolean isReadyForPullStart() {
int firstPosition = getRefreshableView().getFirstVisiblePosition();
RecyclerView.LayoutManager layoutManager = getRefreshableView().getLayoutManager();
View firstView = layoutManager.findViewByPosition(firstPosition);
if(firstView != null) {
int firstTop = firstView.getTop();
return firstPosition == 0 && firstTop >= 0;
}
else{
return true;
}
}
这两个方法会在滑动的时候被调用,判断是否已经到列表顶部或底部,如果到顶部或底部就会执行下拉/上拉的操作了。
逻辑比较简单,判断是否显示了第一个/最后一个item,并且它的top/bottom也显示了(说明这个item完整显示出来了)。
还需要重写另外一个方法
@Override
protected WrapRecyclerView createRefreshableView(Context context, AttributeSet attrs) {
WrapRecyclerView recyclerView = new WrapRecyclerView(context, attrs);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if(isReadyForPullStart()){
recyclerView.clearFocus();
}
}
});
recyclerView.setId(R.id.pulltorefresh_recyclerview);
return recyclerView;
}
这个方法就是创建一个WrapRecyclerView,注意不要忘了setId,否则在Fragment中使用会出现一些问题(回收重建的时候)。
效果
由于基于pulltorefresh库,所有功能库中都实现了,所以重写这几个方法就能实现下拉刷新功能了。实现效果如下
如果想改变显示或风格,可以通过pulltorefresh库的api来实现,关于pulltorefresh库的使用大家可以自行查阅相关文档。
相关文章
- 测试开发工程师到底是做什么的?
- 升讯威在线客服系统客服端英文界面的技术实现方法,客户落地巴西圣保罗
- 一台虚拟机,基于docker搭建大数据HDP集群
- pycharm怎么在新窗口打开项目
- anaconda不能打开Jupyter Notebook解决方法
- php文件怎么在浏览器运行
- Python sklearn中的算法如何使用?
- python3 os中如何回到当前目录?
- 使用python3 os后程序无法运行怎么办?
- python3 re如何快速编译?
- php按值传递和引用传递的比较
- 如何停止spyder中运行的程序
- php文件用什么软件打开
- anaconda 安装好打不开怎么办
- python django框架中的单元测试如何执行?
- pycharm代码不高亮显示怎么办
- ps金属质感怎么做
- ps教程之怎么用ps抠图头发丝
- 怎么在jupyter安装包?
- pycharm怎么设置代码自动提示