RecyclerView and SwipeRefreshLayout

后端 未结 12 1898
再見小時候
再見小時候 2020-12-22 15:46

I\'m using the new RecyclerView-Layout in a SwipeRefreshLayout and experienced a strange behaviour. When scrolling the list back to the top sometim

12条回答
  •  再見小時候
    2020-12-22 16:29

    I have experienced same issue. I solved it by adding scroll listener that will wait until expected first visible item is drawn on the RecyclerView. You can bind other scroll listeners too, along this one. Expected first visible value is added to use it as threshold position when the SwipeRefreshLayout should be enabled in cases where you use header view holders.

    public class SwipeRefreshLayoutToggleScrollListener extends RecyclerView.OnScrollListener {
            private List mScrollListeners = new ArrayList();
            private int mExpectedVisiblePosition = 0;
    
            public SwipeRefreshLayoutToggleScrollListener(SwipeRefreshLayout mSwipeLayout) {
                this.mSwipeLayout = mSwipeLayout;
            }
    
            private SwipeRefreshLayout mSwipeLayout;
            public void addScrollListener(RecyclerView.OnScrollListener listener){
                mScrollListeners.add(listener);
            }
            public boolean removeScrollListener(RecyclerView.OnScrollListener listener){
                return mScrollListeners.remove(listener);
            }
            public void setExpectedFirstVisiblePosition(int position){
                mExpectedVisiblePosition = position;
            }
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                notifyScrollStateChanged(recyclerView,newState);
                LinearLayoutManager llm = (LinearLayoutManager) recyclerView.getLayoutManager();
                int firstVisible = llm.findFirstCompletelyVisibleItemPosition();
                if(firstVisible != RecyclerView.NO_POSITION)
                    mSwipeLayout.setEnabled(firstVisible == mExpectedVisiblePosition);
    
            }
    
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                notifyOnScrolled(recyclerView, dx, dy);
            }
            private void notifyOnScrolled(RecyclerView recyclerView, int dx, int dy){
                for(RecyclerView.OnScrollListener listener : mScrollListeners){
                    listener.onScrolled(recyclerView, dx, dy);
                }
            }
            private void notifyScrollStateChanged(RecyclerView recyclerView, int newState){
                for(RecyclerView.OnScrollListener listener : mScrollListeners){
                    listener.onScrollStateChanged(recyclerView, newState);
                }
            }
        }
    

    Usage:

    SwipeRefreshLayoutToggleScrollListener listener = new SwipeRefreshLayoutToggleScrollListener(mSwiperRefreshLayout);
    listener.addScrollListener(this); //optional
    listener.addScrollListener(mScrollListener1); //optional
    mRecyclerView.setOnScrollLIstener(listener);
    

提交回复
热议问题