我想把ListView改为RecyclerView。我想在RecyclerView中使用OnScrollListener的onScroll来确定用户是否滚动到列表的末尾。

我如何知道用户是否滚动到列表的末尾以便我可以从REST服务获取新数据?


当前回答

我有一个关于如何使用RecyclerView进行分页的非常详细的示例。在高层次,我有一个设置PAGE_SIZE,让我们说30。所以我请求30个项目,如果我得到30个,我就请求下一页。如果我得到的条目少于30个,我就标记一个变量来指示已经到达最后一页,然后停止请求更多的页面。看看吧,告诉我你的想法。

https://medium.com/@etiennelawlor/pagination-with-recyclerview-1cb7e66a502b

其他回答

我检测加载事件的方法不是检测滚动,而是监听最后一个视图是否附加。如果附加了最后一个视图,我认为这是加载更多内容的时机。

class MyListener implements RecyclerView.OnChildAttachStateChangeListener {
    RecyclerView mRecyclerView;

    MyListener(RecyclerView view) {
        mRecyclerView = view;
    }

    @Override
    public void onChildViewAttachedToWindow(View view) {

    RecyclerView.Adapter adapter = mRecyclerView.getAdapter();
    RecyclerView.LayoutManager mgr = mRecyclerView.getLayoutManager();
    int adapterPosition = mgr.getPosition(view);

    if (adapterPosition == adapter.getItemCount() - 1) {
        // last view was attached
        loadMoreContent();
    }

    @Override
    public void onChildViewDetachedFromWindow(View view) {}
}

我的答案是一个改良版的努尔。我从一个ListView,在那里我有EndlessScrollListener(你可以很容易地在SO上找到许多答案)到一个RecyclerView,所以我想要一个endlessrecyscrolllistener轻松地更新我过去的监听器。

下面是代码,希望能有所帮助:

public abstract class EndlessScrollRecyclListener extends RecyclerView.OnScrollListener
{
    // The total number of items in the dataset after the last load
    private int previousTotalItemCount = 0;
    private boolean loading = true;
    private int visibleThreshold = 5;
    int firstVisibleItem, visibleItemCount, totalItemCount;
    private int startingPageIndex = 0;
    private int currentPage = 0;

    @Override
    public void onScrolled(RecyclerView mRecyclerView, int dx, int dy)
    {
        super.onScrolled(mRecyclerView, dx, dy);
        LinearLayoutManager mLayoutManager = (LinearLayoutManager) mRecyclerView
                .getLayoutManager();

        visibleItemCount = mRecyclerView.getChildCount();
        totalItemCount = mLayoutManager.getItemCount();
        firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
        onScroll(firstVisibleItem, visibleItemCount, totalItemCount);
    }

    public void onScroll(int firstVisibleItem, int visibleItemCount, int totalItemCount)
    {
        // If the total item count is zero and the previous isn't, assume the
        // list is invalidated and should be reset back to initial state
        if (totalItemCount < previousTotalItemCount)
        {
            this.currentPage = this.startingPageIndex;
            this.previousTotalItemCount = totalItemCount;
            if (totalItemCount == 0)
            {
                this.loading = true;
            }
        }
        // If it’s still loading, we check to see if the dataset count has
        // changed, if so we conclude it has finished loading and update the current page
        // number and total item count.
        if (loading && (totalItemCount > previousTotalItemCount))
        {
            loading = false;
            previousTotalItemCount = totalItemCount;
            currentPage++;
        }

        // If it isn’t currently loading, we check to see if we have breached
        // the visibleThreshold and need to reload more data.
        // If we do need to reload some more data, we execute onLoadMore to fetch the data.
        if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem +
                visibleThreshold))
        {
            onLoadMore(currentPage + 1, totalItemCount);
            loading = true;
        }
    }

    // Defines the process for actually loading more data based on page
    public abstract void onLoadMore(int page, int totalItemsCount);

}

我让你接近我。对我来说没问题。

我希望这对你有所帮助。

/**
 * Created by Daniel Pardo Ligorred on 03/03/2016.
 */
public abstract class BaseScrollListener extends RecyclerView.OnScrollListener {

    protected RecyclerView.LayoutManager layoutManager;

    public BaseScrollListener(RecyclerView.LayoutManager layoutManager) {

        this.layoutManager = layoutManager;

        this.init();
    }

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

        super.onScrolled(recyclerView, dx, dy);

        this.onScroll(recyclerView, this.getFirstVisibleItem(), this.layoutManager.getChildCount(), this.layoutManager.getItemCount(), dx, dy);
    }

    private int getFirstVisibleItem(){

        if(this.layoutManager instanceof LinearLayoutManager){

            return ((LinearLayoutManager) this.layoutManager).findFirstVisibleItemPosition();
        } else if (this.layoutManager instanceof StaggeredGridLayoutManager){

            int[] spanPositions = null; //Should be null -> StaggeredGridLayoutManager.findFirstVisibleItemPositions makes the work.

            try{

                return ((StaggeredGridLayoutManager) this.layoutManager).findFirstVisibleItemPositions(spanPositions)[0];
            }catch (Exception ex){

                // Do stuff...
            }
        }

        return 0;
    }

    public abstract void init();

    protected abstract void onScroll(RecyclerView recyclerView, int firstVisibleItem, int visibleItemCount, int totalItemCount, int dx, int dy);

}
 recyclerList.setOnScrollListener(new RecyclerView.OnScrollListener() 
            {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx,int dy)
                {
                    super.onScrolled(recyclerView, dx, dy); 
                }

                @Override
                public void onScrollStateChanged(RecyclerView recyclerView,int newState) 
                {
                    int totalItemCount = layoutManager.getItemCount();
                    int lastVisibleItem = layoutManager.findLastVisibleItemPosition();

                    if (totalItemCount> 1) 
                    {
                        if (lastVisibleItem >= totalItemCount - 1) 
                        {
                            // End has been reached
                            // do something 
                        }
                    }          
                }
            });  

这个解决方案对我来说非常有效。

//Listener    

public abstract class InfiniteScrollListener     extendsRecyclerView.OnScrollListener {

public static String TAG = InfiniteScrollListener.class.getSimpleName();
int firstVisibleItem, visibleItemCount, totalItemCount;
private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 1;
private int current_page = 1;

private LinearLayoutManager mLinearLayoutManager;

public InfiniteScrollListener(LinearLayoutManager linearLayoutManager) {
    this.mLinearLayoutManager = linearLayoutManager;
}

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

    visibleItemCount = recyclerView.getChildCount();
    totalItemCount = mLinearLayoutManager.getItemCount();
    firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();

    if (loading) {
        if (totalItemCount > previousTotal) {
            loading = false;
            previousTotal = totalItemCount;
        }
    }
    if (!loading && (totalItemCount - visibleItemCount - firstVisibleItem <= visibleThreshold)) {

        current_page++;

        onLoadMore(current_page);

        loading = true;
    }
}

public void resetState() {
    loading = true;
    previousTotal = 0;
    current_page = 1;
}

public abstract void onLoadMore(int current_page);
}

//Implementation into fragment 
 private InfiniteScrollListener scrollListener;

scrollListener = new InfiniteScrollListener(manager) {
        @Override
        public void onLoadMore(int current_page) {
            //Load data
        }
    };
    rv.setLayoutManager(manager);
    rv.addOnScrollListener(scrollListener);