欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

RecyclerView 如何实现分页加载

程序员文章站 2022-04-14 11:12:54
我之前工作内容是维护旧的项目,而旧的项目里面用的几乎都是listview,后面公司来了个新的产品经理,他一来就吐槽我们的app,每次获取新的一页列表后,所有列表项(包括前面几页的列表项)都是要全部刷新一遍,这个体验太差了,他说要实现局部刷新,才符合要求。我只好硬着头皮把项目里面的listview慢慢换成RecyclerView. 换成RecyclerView之后,很棘手的一个问题就是,分页问题。因为之前的listview分页都是别人在listview的基础上封装了一个专门用来刷新的Refres......

我之前工作内容是维护旧的项目,而旧的项目里面用的几乎都是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局部刷新数据和分页加载的目的。希望有高手指点一下,看还有没有更加简单优化的实现方案

本文地址:https://blog.csdn.net/lilimm111/article/details/108973831