用户登录
用户注册

分享至

RecyclerView 如何实现分页加载

  • 作者: 小宝很社会
  • 来源: 51数据库
  • 2021-08-21

我之前工作内容是维护旧的项目,而旧的项目里面用的几乎都是listview,后面公司来了个新的产品经理,他一来就吐槽我们的app,每次获取新的一页列表后,所有列表项(包括前面几页的列表项)都是要全部刷新一遍,这个体验太差了,他说要实现局部刷新,才符合要求。我只好硬着头皮把项目里面的listview慢慢换成RecyclerView.

? ? ? 换成RecyclerView之后,很棘手的一个问题就是,分页问题。因为之前的listview分页都是别人在listview的基础上封装了一个专门用来刷新的RefreshListView。我一开始自作聪明的把RefreshListView继承的ListView换成RecyclerView,没想到引出一大堆的问题,网上搜索各种解决方案,最后发现代码越来越臃肿,我实在看不下去了。后面打算直接用RecyclerView,分页问题再另外想办法来实现。

我总结了两种情况下用RecyclerView实现分页效果:

第一种情况,页面中,只使用RecyclerView为滑动控件(没有在外层添加NetScollview或者Scollview)

1.实现分页代码:
int p=1;//第几页
int pSize=10;//每页最大item数量
private int lastItemPosition;
void setScollNextPage(){
    rlistview.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            if (newState == SCROLL_STATE_IDLE &&
                    lastItemPosition == adapter.getItemCount()){
                if(isNext) {
                    p++;
                    getNextPageData();
                }

            }
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

            RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
            if (layoutManager instanceof LinearLayoutManager){
                LinearLayoutManager manager = (LinearLayoutManager) layoutManager;
                int firstVisibleItem = manager.findFirstVisibleItemPosition();
                int l = manager.findLastCompletelyVisibleItemPosition();
                lastItemPosition = firstVisibleItem+(l-firstVisibleItem)+1;

            }
        }
    });
}

2.实现局部刷新代码:

void?getNextPageData(){

//获取下一页数据

//新的数据为newlist,当前list的size=pos

if (p == 1) {

    adapter.notifyDataSetChanged();//当页面为1,直接刷新所有数据

} else {
    if (newlist != null && newlist.size() > 0) {
        adapter.notifyItemRangeChanged(pos, newlist.size());//pos为插入的列表开始位置,插入的大小为新的数据列表大小
    }
}

?

?

第二种情况,RecyclerView 外层包着Scollview或者NetScollview

如果用第一种情况的方法,会发现,上述方法不起作用。所以我把滑动的事件放在Scollview或者NetScollview上

1. 先重写了一个MScollview extends NetScollview(或者 Scollview)

在MScollview 里面重写了方法

MListener?mListener;

@Override
protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
    super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
    if (scrollY != 0 && mListener != null) {
        mListener.onMyScroll(clampedY);
    }
}

public interface MListener {

? ? void onMyScroll(boolean c); //滑动到底部回调方法

}

public setMlistener(MListener mlisterner){

mListener=mlisterner;

}

2.在Activity或者fragement 中使用MScollview(layout 布局中同样要使用重写后的MScollview)

MScollview mScollview ;

mScollview. setMlistener(new MListener (){

void onMyScroll(boolean c){

? ? ? if(c){

p++;//页码加1

getNextPageData();//获取下一页数据的方法

}

}

})

?

最后,以上方法,还存在一些不足,在这里,我就没有写出来了,这两个方法都是比较简单粗暴,可以实现用RecyclerView局部刷新数据和分页加载的目的。希望有高手指点一下,看还有没有更加简单优化的实现方案

软件
前端设计
程序设计
Java相关