转载请附原文链接:
1 需求分析
最近公司项目要实现一个需求要满足以下功能:
1)显示一个 list 列表, item 数量不固定。
2)实现翻页功能,一次翻一页。
3)实现翻至某一页功能。
4)实现一次翻几页功能。
下面介绍通过 RecyclerView 实现该需求的实现过程(效果图如下)。
2 功能实现
2.1 OnTouchListener 记录当前开始滑动位置
要实现翻页滑动首先我们要确定是向前翻页还是向后翻页,这里通过记录开始翻页前当前的位置和滑动后的位置比较即可得知,下面选择手指触摸按下时滑动的位置为当前开始滑动位置:
|
|
好了,当我们确定了滑动方向,下面要考虑的就是如何实现滑动?
2.2 scrollTo(int x, int y) 和 scrollBy(int x, int y) 实现滑动
滑动我们最容易想到的方法就是 scrollTo(int x, int y)
和 scrollBy(int x, int y)
这两个方法, scrollTo(int x, int y)
是将当前 View 的内容滑动至某一位置, scrollBy(int x, int y)
是将当前 View 内容相对于当前位置滑动一定的距离,其实 scrollBy(int x, int y)
内部是调用了 scrollTo(int x, int y)
方法实现的 一开始想用 scrollTo(int x, int y)
去实现,但是简单看了下源码发现, RecyclerView 不支持这个方法:
|
|
所以这里我们就选择使用 scrollBy(int x, int y)
去实现滑动。
2.3 OnFlingListener
和 OnScrollListener
调用滑动时机
上面我们决定使用 scrollBy(int x, int y)
去实现滑动,那么现在我们就要确定 scrollBy(int x, int y)
这个方法的调用时机,我们知道当我们滑动 RecyclerView 的时候一般分为两种情况,一种是手指在屏幕上面缓慢滑动(Scroll),另一种是飞速滑动(onFling),经过一番查阅,发现 RecyclerView 中有这两种状态的监听,那么我们一起看一下这两种状态的方法定义,先看 onFling(int velocityX, int velocityY)
:
Note: 由于使用了 RecyclerView 的 OnFlingListener,所以 RecycleView 的版本必须要 recyclerview-v7:25.0.0 以上。
|
|
方法的注释写的也很清楚,当这个方法被调用并且返回 true 的时候系统就不处理滑动了,而是将滑动交给我们自己处理。所以我们可以监听这个方法,当我们执行快速滑动的时候在这个方法里面计算要滑动的距离并执行 scrollBy(int x, int y)
实现滑动,然后直接返回 true,表示滑动我们自己处理了,不需要系统处理。处理代码如下:
|
|
再看 OnScrollListener
滚动监听方法:
|
|
这个监听类主要有两个方法一个是 onScrollStateChanged(RecyclerView recyclerView, int newState)
滚动状态发生变化调用, onScrolled(RecyclerView recyclerView, int dx, int dy)
RecyclerView 发生滚动和滚动完成调用。有了这两个监听,当我们进行缓慢滑动我们就可以在 onScrollStateChanged(RecyclerView recyclerView, int newState)
中监听滑动如果结束并且超过一定距离去执行翻页,而通过 onScrolled(RecyclerView recyclerView, int dx, int dy)
方法可以记录当前的滑动距离。处理方法如下:
|
|
到这里我们要实现滑动的方法和时机基本就搞定了,剩下的就是滑动位置计算和滑动效果实现,滑动位置计算就是一次滑动一整页,这个没什么可说的,所以简单说下实现弹性滑动效果。
2.4 ValueAnimator 实现弹性滑动效果
我们知道如果我们直接调用 scrollBy(int x, int y)
这个方法去滑动,那么是没有缓慢滑动的效果,看着有点愣,所以这里我们通过 ValueAnimator 这个类来实现缓慢滑动的效果,这个就很简单了,直接贴代码:
|
|
2.5 翻页至某一页
这里翻页至某一页的实现有了上面的基础就很好实现了,就是直接调用 我们已经实现好了的 onFling(int velocityX, int velocityY)
方法,然后把页数传递过去计算一下就可以了 :
|
|
2.6 一次翻 n 页
|
|
2.7 滑动至某点
|
|
滑动至某一点这里是通过 LinearLayoutManager.scrollToPositionWithOffset(int position, int offset)
这个方法实现的,因为 RecyclerView. scrollTo(int x, int y)
这个方法无法实现滑动,如果你有更好的方法也求分享下 ^^。
2.8 滑动一定距离
|
|
到这里前面说的功能已经全部实现完毕,具体代码细节请见 github 地址: pagerecyclerview
参考文章: