RecyclerView的滚动事件OnScrollListener

匿名 (未验证) 提交于 2019-12-03 00:18:01
RecyclerView的滚动事件OnScrollListener

(1)滚动事件分类

列表的滚动一般分为两种:

 1.手指按下 -> 手指拖拽列表移动 -> 手指停止拖拽 -> 抬起手指  2.手指按下 -> 手指快速拖拽后抬起手指 -> 列表继续滚动 -> 停止滚动

上面的过程的状态变化如下:

1.静止 -> 被迫拖拽移动 -> 静止 2.静止 -> 被迫拖拽移动 -> 自己滚动 -> 静止

(2)监听RecyclerView的滚动

有两种方式可以监听滚动事件:

  1.setOnScrollListener(OnScrollListener listener)  //被废弃   2.addOnScrollListener(OnScrollListener listener)

其中 setOnScrollListener 由于可能出现空指针的风险,已经过时。建议用addOnScrollListener。

(3)OnScrollListener

/**  * 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(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(RecyclerView recyclerView, int dx, int dy){} }

OnScrollListener类是个抽象类,有两个方法:

void onScrollStateChanged(RecyclerView recyclerView, int newState): 滚动状态变化时回调 void onScrolled(RecyclerView recyclerView, int dx, int dy): 滚动时回调

3.1 onScrollStateChanged(RecyclerView recyclerView, int newState)方法

回调的两个变量的含义:
recyclerView: 当前在滚动的RecyclerView
newState: 当前滚动状态.

其中newState有三种值:

/**  * The RecyclerView is not currently scrolling.(静止没有滚动)  */ public static final int SCROLL_STATE_IDLE = 0;  /**  * The RecyclerView is currently being dragged by outside input such as user touch input.  *(正在被外部拖拽,一般为用户正在用手指滚动)  */ public static final int SCROLL_STATE_DRAGGING = 1;  /**  * The RecyclerView is currently animating to a final position while not under outside control.  *(自动滚动)  */ public static final int SCROLL_STATE_SETTLING = 2;

3.2 onScrolled(RecyclerView recyclerView, int dx, int dy)方法

回调的三个变量含义:
recyclerView : 当前滚动的view
dx : 水平滚动距离
dy : 垂直滚动距离

dx > 0 时为手指向左滚动,列表滚动显示右面的内容
dx < 0
时为手指向右滚动,列表滚动显示左面的内容
dy > 0
时为手指向上滚动,列表滚动显示下面的内容
dy < 0
时为手指向下滚动,列表滚动显示上面的内容

(4)canScrollVertically和canScrollHorizontally方法

public boolean canScrollVertically (int direction) 这个方法是判断View在竖直方向是否还能向上,向下滑动。 其中,direction为 -1 表示手指向下滑动(屏幕向上滑动), 1 表示手指向上滑动(屏幕向下滑动)。  public boolean canScrollHorizontally (int direction) 这个方法用来判断 水平方向的滑动

例如:
RecyclerView.canScrollVertically(1)的值表示是否能向下滚动,false表示已经滚动到底部
RecyclerView.canScrollVertically(-1)的值表示是否能向上滚动,false表示已经滚动到顶部

(5)两种判断是否到底部的方法:

5.1方法一:

如果 当前
第一个可见item的位置 + 当前可见的item个数 >= item的总个数
这样就可以判断出来,是在底部了。

loadingMoreListener = 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);              if (dy > 0) //向下滚动             {                 int visibleItemCount = mLinearLayoutManager.getChildCount();	//得到显示屏幕内的list数量                 int totalItemCount = mLinearLayoutManager.getItemCount();	//得到list的总数量                 int pastVisiblesItems = mLinearLayoutManager.findFirstVisibleItemPosition();//得到显示屏内的第一个list的位置数position                  if (!loading && (visibleItemCount + pastVisiblesItems) >= totalItemCount) {                     loading = true;                     loadMoreDate();                 }             }         } };

通过
visibleItemCount + pastVisiblesItems) >= totalItemCount
来判断是否是底部。

5.2方法二:

通过canScrollVertically 来判断

loadingMoreListener = new RecyclerView.OnScrollListener() {     @Override     public void onScrollStateChanged(RecyclerView recyclerView, int newState) {         super.onScrollStateChanged(recyclerView, newState);         if(!loading && !recyclerView.canScrollVertically(1)){             loading = true;             loadMoreDate();         }     }      @Override     public void onScrolled(RecyclerView recyclerView, int dx, int dy) {         super.onScrolled(recyclerView, dx, dy);  //                if (dy > 0) //向下滚动 //                { //                    int visibleItemCount = mLinearLayoutManager.getChildCount(); //                    int totalItemCount = mLinearLayoutManager.getItemCount(); //                    int pastVisiblesItems = mLinearLayoutManager.findFirstVisibleItemPosition(); // //                    if (!loading && (visibleItemCount + pastVisiblesItems) >= totalItemCount) { //                        loading = true; //                        loadMoreDate(); //                    } //                }     } };

参考:

http://blog.devwiki.net/index.php/2016/06/13/RecyclerView-Scroll-Listener.html

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!