Android——RecyclerView自定义OnScrollListener实现下拉刷新监听,上拉加载更多功能

目录

【前言】

1、OnScrollListener滑动事件监听抽象类

2、利用onScrollStateChanged及onScrolled方法实现下拉刷新及上拉加载更多

3、使用方法

4、利用SwipeRefreshLayout实现下拉刷新效果


【前言】

针对RecyclerView有很多开源的框架可以直接拿来用,比较有代表性的是BaseRecyclerViewAdapterHelper,功能很强大,具备上拉监听的功能。使用开源的东西固然省时省力,但是前期自定义的Adapter使用较多,不想再更改了,且总使用开源的东西慢慢人都变傻了,这个功能不算复杂,就自己查找相关资料参照实现了。

1、OnScrollListener滑动事件监听抽象类

这个抽象类是我们要实现下拉刷新,上拉加载的关键,其中有onScrollStateChanged  、onScrolled两个方法

  • onScrollStateChanged:滑动状态改变时方法会被调用,第一个参数recyclerView是当前的列表,第二个参数newState是滑动状态(SCROLL_STATE_IDLE为无滑动,SCROLL_STATE_SETTLING为滑动中);
  • onScrolled:滑动状态改变时方法会被调用,第一个参数recyclerView是当前的列表,xy为水平、垂直方向滑动坐标值,所以垂直方向,当y值>0时,说明列表正在向上滑动,<=0时列表向下滑动或停止。
 /**
     * An OnScrollListener can be added to a RecyclerView to receive messages when a scrolling event
     * has occurred on that RecyclerView.
     * <p>
     * @see RecyclerView#addOnScrollListener(OnScrollListener)
     * @see RecyclerView#clearOnChildAttachStateChangeListeners()
     *
     */
    public abstract static class OnScrollListener {
        /**
         * Callback method to be invoked when RecyclerView's scroll state changes.
         *
         * @param recyclerView The RecyclerView whose scroll state has changed.
         * @param newState     The updated scroll state. One of {@link #SCROLL_STATE_IDLE},
         *                     {@link #SCROLL_STATE_DRAGGING} or {@link #SCROLL_STATE_SETTLING}.
         */
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState){}

        /**
         * Callback method to be invoked when the RecyclerView has been scrolled. This will be
         * called after the scroll has completed.
         * <p>
         * This callback will also be called if visible item range changes after a layout
         * calculation. In that case, dx and dy will be 0.
         *
         * @param recyclerView The RecyclerView which scrolled.
         * @param dx The amount of horizontal scroll.
         * @param dy The amount of vertical scroll.
         */
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){}
    }

2、利用onScrollStateChanged及onScrolled方法实现下拉刷新及上拉加载更多

结合以上对两个方法及参数的说明,可知,结合这两个方法可判断出当前是下滑还是上滑动作,覆写方法,结合加入可视区域第一条和最后一条item的位置,可以判断出下拉、上拉的动作,因此完全可以自定义RecyclerView.OnScrollListener实现,关键思路:

  • 下拉:可视区域第一条item位置==0 && 非上滑动作;
  • 上拉:可视区域最后条item位置==列表item总数-1 && 上滑动作;
  • 接口:定义回调接口,内部定义下拉刷新,及上拉加载更多两个方法,外部调用时覆写两个方式实现自己的业务逻辑。

完整的自定义RecyclerView.OnScrollListener代码如下:

public  class RecyclerViewOnScrollListener extends RecyclerView.OnScrollListener {
    //监听回调
    private UpPullOnScrollListener listener;

    public RecyclerViewOnScrollListener(UpPullOnScrollListener listener) {
        this.listener = listener;
    }

    boolean isUpScroll = false; //是否正在上滑标记
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();

        if (newState == RecyclerView.SCROLL_STATE_IDLE) { //当前未滑动

            int itemCount = manager.getItemCount(); //总数
            int lastItemPosition = manager.findLastCompletelyVisibleItemPosition();//最后显示的位置

            if (lastItemPosition == (itemCount - 1) && isUpScroll) {
                listener.onLoadMore();
            }
            int fristItemPosition = manager.findFirstCompletelyVisibleItemPosition();//第一个显示的位置
            if (fristItemPosition == (0) && !isUpScroll){
                listener.onRefresh();
            }
        }
    }
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        // 大于0表示正在向上滑动,小于等于0表示停止或向下滑动
        isUpScroll = dy > 0;
    }

    public interface UpPullOnScrollListener {
        public  void onLoadMore() ; //上拉加载更多的方法
        public   void onRefresh() ; //下拉刷新的方法
    }

}

3、使用方法

1)RecyclerView的 public void addOnScrollListener(@NonNull OnScrollListener listener) 方法实现列表滑动事件的监听,传入的对象为OnScrollListener;

2)用自定义的RecyclerView.OnScrollListener写一个自己业务处理的监听器,eg:

private RecyclerViewOnScrollListener.UpPullOnScrollListener onScrollListener = new RecyclerViewOnScrollListener.UpPullOnScrollListener() {
        @Override
        public void onLoadMore() { //上拉处理逻辑
            
        }

        @Override
        public void onRefresh() {  //下拉刷新不在此处处理,使用的swipeRefreshLayout实现

        }
    };

3)调用监听即可:recyclerView.addOnScrollListener(new RecyclerViewOnScrollListener(onScrollListener));

4、利用SwipeRefreshLayout实现下拉刷新效果

用这个layout实现的下拉刷新效果更好看一些,而且也很方便,此处只写注意要点:

1)布局时 SwipeRefreshLayout 包裹 RecyclerView;

2)所在类实现SwipeRefreshLayout.OnRefreshListener接口;

3)SwipeRefreshLayout实例化对象设置刷新监听setOnRefreshListener(this);

4)覆写public void onRefresh()方法,其中写自己的刷新业务逻辑。

发布了86 篇原创文章 · 获赞 53 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/w464960660/article/details/104800632