如何使 ListView 或 RecyclerView 继续自动加载更多数据直到屏幕填满

How to make a ListView or RecyclerView continue to load more data automatically until screen is filled

我正在 RecyclerView 中显示一组项目。数据从服务器下载,每次下载一组item。但是,有时只有一组数据不能填满屏幕,所以我想让RecyclerView能够检测到这个问题,并开始加载下一组数据,直到填满屏幕。

比如第1页数据不够就加载第2页数据,还不够就加载第3页数据,以此类推。

检测部分并不难,因为我可以得到以下参数:

    int visibleItemCount = mLayoutManager.getChildCount();
    int totalItemCount = mLayoutManager.getItemCount();
    int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();

但问题是notifyDataSetChanged()。例如,下面是我设置数据的代码:

public void setData(List data){
    updataData(data);
    mAdapter.notifyDataSetChanged();
    if(ifScreenNotFilled()){
       loadNextGroupData(); // it calls 'setData()' recursively
    }
}

调用loadNextGroupData()时,递归调用setData。结果数据列表的大小一直在扩大,而visibleItemCount一直为零,屏幕上什么也没有显示。

如果我删除代码的递归部分,第一组数据将加载到屏幕中。我对notifyDataSetChanged().

的机制很好奇

那么有没有办法让RecyclerView在没有填满屏幕时自动更新?

尝试在您的 mRecyclerView 上使用 getHeight() 并获取它的高度并将其与显示高度进行比较。

    int height = getWindow().getWindowManager().getDefaultDisplay().getHeight()

我找到了 notifyDataSetChanged() 不起作用的原因。这是因为 setData() 方法的递归调用使它永远不会 returns。因此 notifyDataSetChanged() 无法由 UI 线程执行。

解决方案是使用 Handler 将递归部分 post 放入 UI 线程的消息队列中。

mHandler = new Handler(Looper.getMainLooper());
public void setData(List data){
    updataData(data);
    mAdapter.notifyDataSetChanged();
    if(ifScreenNotFilled()){
       mHandler.post(new Runnable(){
             @override 
             public void run(){
                 loadNextGroupData();
             }
        }
    }
}

后面看到这个问题的朋友,上面代码的具体实现可以在我的repo中找到:https://github.com/SphiaTower/AutoPagerRecyclerManager .

请检查https://github.com/SphiaTower/AutoPagerRecyclerManager/blob/master/lib/src/main/java/tower/sphia/auto_pager_recycler/lib/AutoPagerRecyclerViewManager.java中的setData()方法