RecyclerView滚动事件分析与OnScrollListener的使用

  • A+
所属分类:Android

作为一个目前在Android开发中可能是应用最为广泛之一的组件,RecyclerView在诞生之初就广受好评。而随着对其研究的深入,我们会对它有很多使用需求,一个能滚动的组件,需要监控其滚动事件是非常正常的事情。

一、列表的滚动事件:

一个列表在滚动的时候,一般会有两种滚动形式:

  • 手指按下后,不离开屏幕,一直拖动着列表进行滚动,滚动到合适的位置后停下来,手指离开屏幕。
  • 手指按下,在很短时间内用较快的速度拖动列表,然后手指马上离开列表,列表随着惯性,继续滚动到一个位置(或者滚动到尾部)。

二、如何监听RecyclerView的滚动事件

稍有经验的开发者,都不难猜到会有一个Listener,在Android Studio里面直接用一个RecyclerView对象进行set或者add的时候,IDE就会提示相应的Listener。是的,Google给我们提供了一个RecyclerView下的OnScrollListener,你可以用addOnScrollListener或setOnScrollListener(已经deprecated了,不建议使用)的方式来监听,下面我们来看看它的源码:

OnScrollListener提供了2个回掉方法,但由于OnScrollListener不是接口而是抽象类,所以你并不是必须同时实现这2个方法,可以根据实际需求来进行实现。下面来看一下这2个方法都有什么作用。

onScrollStateChanged(RecyclerView recyclerView, int newState)

很容易看出来,这个方法记录了RecyclerView的滚动状态的变化,2个变量中,第一个自然是当前的RecyclerView组件,第二个则表达了当前滚动状态,它有3个值:

我特别欣慰,这次Google自己写的注释很详细了。当然如果你英语水平不高我可以给你翻译一下:

  • SCROLL_STATE_IDLE代表RecyclerView现在不是滚动状态。
  • SCROLL_STATE_DRAGGING代表RecyclerView处于被外力引导的滚动状态,比如手指正在拖着进行滚动。
  • SCROLL_STATE_SETTLING代表RecyclerView处于自动滚动的状态,此时手指已经离开屏幕,RecyclerView的滚动是自身的惯性在维持。

onScrolled(RecyclerView recyclerView, int dx, int dy)

此方法用来获取RecyclerView的滚动距离,dx和dy自然分别代表横向和纵向的滚动距离啦,这2个值都是可正可负的:

  • 当dx > 0 时,代表手指向左拖动,RecyclerView则从右向左滚动。
  • 当dx < 0时,代表手指向右拖动,RecyclerView则从左向右滚动。
  • 当dy > 0时,代表手指向上拖动,RecyclerView则从上向下滚动(就是我们最常见的,从顶部开始往下滚动)。
  • 当dy < 0时,代表手指向下拖动,RecyclerView则从下向上滚动(就是从列表底部往回挥动)。

这里再介绍2个很有用的方法:

  • public boolean canScrollVertically(int direction)
  • public boolean canScrollHorizontally(int direction)

这2个方法实际上并不是RecyclerView所特有的,而是View这个超级类的。这2个方法,可以判断当前View能否在横向或纵向上滚动。当返回false的时候,说明组件已经不能在给定的方向上进行滚动了,而这2个方法,也可以引出一个很常见的问题及解决办法。

三、如何判断RecyclerView是否滚动到底部或顶部?

以更常见的纵向来说,使用Recyclerview. canScrollVertically(1),当返回值是false的时候,代表你的RecyclerView不能继续往下滚动啦,也就是说已经滚动到底部了。同理,当Recyclerview. canScrollVertically(-1)返回false的时候代表RecyclerView不能继续网上滚动了,已经到顶部了。这个方法比通过计算当前item的位置以及总item数量的方法进行判断要好多了。

KaelLi

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: