How to implement endless list with RecyclerView?

前端 未结 30 2547
无人及你
无人及你 2020-11-22 02:22

I would like to change ListView to RecyclerView. I want to use the onScroll of the OnScrollListener in RecyclerView to determine if a

相关标签:
30条回答
  • 2020-11-22 03:06

    I achieved an infinite scrolling type implementation using this logic in the onBindViewHolder method of my RecyclerView.Adapter class.

        if (position == mItems.size() - 1 && mCurrentPage <= mTotalPageCount) {
            if (mCurrentPage == mTotalPageCount) {
                mLoadImagesListener.noMorePages();
            } else {
                int newPage = mCurrentPage + 1;
                mLoadImagesListener.loadPage(newPage);
            }
        }
    

    With this code when the RecyclerView gets to the last item, it increments the current page and callbacks on an interface which is responsible for loading more data from the api and adding the new results to the adapter.

    I can post more complete example if this isn't clear?

    0 讨论(0)
  • 2020-11-22 03:06

    None of these answers take into account if the list is too small or not.

    Here's a piece of code I've been using that works on RecycleViews in both directions.

    @Override
        public boolean onTouchEvent(MotionEvent motionEvent) {
    
            if (recyclerViewListener == null) {
                return super.onTouchEvent(motionEvent);
            }
    
            /**
             * If the list is too small to scroll.
             */
            if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                if (!canScrollVertically(1)) {
                    recyclerViewListener.reachedBottom();
                } else if (!canScrollVertically(-1)) {
                    recyclerViewListener.reachedTop();
                }
            }
    
            return super.onTouchEvent(motionEvent);
        }
    
        public void setListener(RecyclerViewListener recycleViewListener) {
            this.recyclerViewListener = recycleViewListener;
            addOnScrollListener(new OnScrollListener() {
    
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
    
                    if (recyclerViewListener == null) {
                        return;
                    }
    
                    recyclerViewListener.scrolling(dy);
    
                    if (!canScrollVertically(1)) {
                        recyclerViewListener.reachedBottom();
                    } else if (!canScrollVertically(-1)) {
                        recyclerViewListener.reachedTop();
                    }
                }
    
            });
        }
    
    0 讨论(0)
  • 2020-11-22 03:07

    For those who only want to get notified when the last item is totally shown, you can use View.canScrollVertically().

    Here is my implementation:

    public abstract class OnVerticalScrollListener
            extends RecyclerView.OnScrollListener {
    
        @Override
        public final void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            if (!recyclerView.canScrollVertically(-1)) {
                onScrolledToTop();
            } else if (!recyclerView.canScrollVertically(1)) {
                onScrolledToBottom();
            } else if (dy < 0) {
                onScrolledUp();
            } else if (dy > 0) {
                onScrolledDown();
            }
        }
    
        public void onScrolledUp() {}
    
        public void onScrolledDown() {}
    
        public void onScrolledToTop() {}
    
        public void onScrolledToBottom() {}
    }
    

    Note: You can use recyclerView.getLayoutManager().canScrollVertically() if you want to support API < 14.

    0 讨论(0)
  • 2020-11-22 03:07

    I let you my aproximation. Works fine for me.

    I hope it helps you.

    /**
     * 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);
    
    }
    
    0 讨论(0)
  • 2020-11-22 03:09

    I have a pretty detailed example of how to paginate with a RecyclerView. At a high level, I have a set PAGE_SIZE , lets say 30. So I request 30 items and if I get 30 back then I request the next page. If I get less than 30 items I flag a variable to indicate that the last page has been reached and then I stop requesting for more pages. Check it out and let me know what you think.

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

    0 讨论(0)
  • 2020-11-22 03:10

    There is a method public void setOnScrollListener (RecyclerView.OnScrollListener listener) in https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#setOnScrollListener%28android.support.v7.widget.RecyclerView.OnScrollListener%29. Use that

    EDIT:

    Override onScrollStateChanged method inside the onScrollListener and do this

                boolean loadMore = firstVisibleItem + visibleItemCount >= totalItemCount;
    
                //loading is used to see if its already loading, you have to manually manipulate this boolean variable
                if (loadMore && !loading) {
                     //end of list reached
                }
    
    0 讨论(0)
提交回复
热议问题