1 . 前言
在一些特定的场景下,如照片的浏览,卡片列表滑动浏览,我们希望当滑动停止时可以将当前的照片或者卡片停留在屏幕中央,以吸引用户的焦点。在Android 中,我们可以使用RecyclerView + Snaphelper来实现,SnapHelper旨在支持RecyclerView的对齐方式,也就是通过计算对齐RecyclerView中TargetView 的指定点或者容器中的任何像素点(包括前面说的显示在屏幕中央)。本篇文章将详细介绍SnapHelper的相关知识点。本文目录如下:
![3513995-aafe6c4113148c23.png](https://img-blog.csdnimg.cn/img_convert/a83294cfd0fd0650be4e541186328398.png)
2 . SnapHelper 介绍
Google 在 Android 24.2.0 的support 包中添加了SnapHelper,SnapHelper是对RecyclerView的拓展,结合RecyclerView使用,能很方便的做出一些炫酷的效果。SnapHelper到底有什么功能呢?SnapHelper旨在支持RecyclerView的对齐方式,也就是通过计算对齐RecyclerView中TargetView 的指定点或者容器中的任何像素点。,可能有点不好理解,看了后文的效果和原理分析就好理解了。看一下文档介绍:
![3513995-7dda1bed6d09f127.png](https://img-blog.csdnimg.cn/img_convert/46c5feee3f0c1ce4b9249e19300c87cd.png)
SnapHelper继承自RecyclerView.OnFlingListener
,并实现了它的抽象方法onFling
, 支持SnapHelper的RecyclerView.LayoutManager
必须实现RecyclerView.SmoothScroller.ScrollVectorProvider
接口,或者你自己实现onFling(int,int)
方法手动处理。SnapHeper 有以下几个重要方法:
attachToRecyclerView: 将SnapHelper attach 到指定的RecyclerView 上。
calculateDistanceToFinalSnap: 复写这个方法计算对齐到TargetView或容器指定点的距离,这是一个抽象方法,由子类自己实现,返回的是一个长度为2的int 数组out,out[0]是x方向对齐要移动的距离,out[1]是y方向对齐要移动的距离。
calculateScrollDistance: 根据每个方向给定的速度估算滑动的距离,用于Fling 操作。
findSnapView:提供一个指定的目标View 来对齐,抽象方法,需要子类实现
findTargetSnapPosition:提供一个用于对齐的Adapter 目标position,抽象方法,需要子类自己实现。
onFling:根据给定的x和 y 轴上的速度处理Fling。
3 . LinearSnapHelper & PagerSnapHelper
上面讲了SnapHelper的几个重要的方法和作用,SnapHelper是一个抽象类,要使用SnapHelper,需要实现它的几个方法。而 Google 内置了两个默认实现类,LinearSnapHelper
和PagerSnapHelper
,LinearSnapHelper可以使RecyclerView 的当前Item 居中显示(横向和竖向都支持),PagerSnapHelper看名字可能就能猜到,使RecyclerView 像ViewPager一样的效果,每次只能滑动一页(LinearSnapHelper支持快速滑动), PagerSnapHelper也是Item居中对齐。接下来看一下使用方法和效果。
(1) LinearSnapHelperLinearSnapHelper
使当前Item居中显示,常用场景是横向的RecyclerView, 类似ViewPager效果,但是又可以快速滑动(滑动多页)。代码如下:
LinearLayoutManager manager = new LinearLayoutManager(getContext());
manager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(manager);
// 将SnapHelper attach 到RecyclrView
LinearSnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(mRecyclerView);
代码很简单,new 一个SnapHelper对象,然后 Attach到RecyclerView 即可。
效果如下:
![3513995-d61d95e08b8ca57f.gif](https://img-blog.csdnimg.cn/img_convert/dcb47fe07434461ad9ac7908ba9d8400.gif)
上面的效果为LayoutManager的方向为VERTICAL,那么接下来看一下横向效果,很简单,和上面的区别只是更改一下LayoutManager的方向,代码如下: