如何识别RecyclerView的最后一项是否在屏幕上可见?

Raj*_*hti 19 android endlessscroll android-recyclerview

我有一个RecyclerView,我添加了数据列表RecyclerView.当RecyclerView屏幕上显示最后一项时,我想在列表中添加更多数据.之后我想进行Web服务调用并更新RecyclerView数据.我怎样才能做到这一点?

有什么建议?

Gil*_*yof 18

有几种方法可以实现这一点,但一种方法是使用适配器的onBindViewHolder方法:

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (position == mData.length - 1) {
            // load more data here.
        }

        /// binding logic
    }
Run Code Online (Sandbox Code Playgroud)

当使用数据源的最后一个位置调用bind方法时,这是一个很好的指示,即最后一个单元格将要显示,并且是触发重新加载调用的好时机.您可能需要为条件添加其他安全措施,以确保您尚未加载更多数据,但这应该可以帮助您入门.

另一种选择是涉及编辑你的LayoutManager.这里的想法是找到最后一个可见项目的位置.如果该位置等于数据集的最后一项,则应触发重新加载.此调用应在您的LayourManager's onLayoutChildren&scrollVerticallyBy(假设您使用垂直滚动)方法中完成:

    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {

        final int result = super.scrollVerticallyBy(dy, recycler, state);

        if (findLastVisibleItemPosition() == mData.length - 1) {
           loadMoreData();
        } 

        return result;

    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        super.onLayoutChildren(recycler, state);

        if (findLastVisibleItemPosition() == mData.length - 1) {
           loadMoreData();
        } 
    }
Run Code Online (Sandbox Code Playgroud)

与以前一样,您需要确保不会多次触发数据加载,因为这种情况可能不止一次发生.

希望这可以帮助!

  • **极不正确的答案**。`onBindViewHolder()` 函数不是 _add/load_ 数据的地方。请不要使用这种技术。 (2认同)

vel*_*val 9

如果有人偶然发现这篇文章,这是一个关于如何做到这一点的快速而简单的教程:

你需要做的就是:

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);
        int visibleItemCount        = lm.getChildCount();
        int totalItemCount          = lm.getItemCount();
        int firstVisibleItemPosition= lm.findFirstVisibleItemPosition();

        // Load more if we have reach the end to the recyclerView
        if ( (visibleItemCount + firstVisibleItemPosition) >= totalItemCount && firstVisibleItemPosition >= 0) {
            loadMoreItems();
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

然后你的loadMoreItems()看起来像这样:

private void loadMoreItems() {
    // init offset=0 the frist time and increase the offset + the PAGE_SIZE when loading more items
    queryOffset = queryOffset + PAGE_SIZE;
    // HERE YOU LOAD the next batch of items
    List<Items> newItems = loadItems(queryOffset, PAGE_SIZE);

    if (newItems.size() > 0) {
        items.addAll(newItems);
        adapter.notifyDataSetChanged();
    }
}
Run Code Online (Sandbox Code Playgroud)