Android中使用RecyclerView + SnapHelper实现类似ViewPager效果

    Google 在 Android 24.2.0 的support 包中添加了SnapHelper,SnapHelper是对RecyclerView的拓展,结合RecyclerView使用,能很方便的做出一些炫酷的效果。SnapHelper到底有什么功能呢?SnapHelper旨在支持RecyclerView的对齐方式,也就是通过计算对齐RecyclerView中TargetView 的指定点或者容器中的任何像素点。,可能有点不好理解,看了后文的效果和原理分析就好理解了。看一下文档介绍:

SnapHealper 介绍.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。

LinearSnapHelper & PagerSnapHelper

上面讲了SnapHelper的几个重要的方法和作用,SnapHelper是一个抽象类,要使用SnapHelper,需要实现它的几个方法。而 Google 内置了两个默认实现类,LinearSnapHelperPagerSnapHelper ,LinearSnapHelper可以使RecyclerView 的当前Item 居中显示(横向和竖向都支持),PagerSnapHelper看名字可能就能猜到,使RecyclerView 像ViewPager一样的效果,每次只能滑动一页(LinearSnapHelper支持快速滑动), PagerSnapHelper也是Item居中对齐。接下来看一下使用方法和效果。

(1) LinearSnapHelper
LinearSnapHelper 使当前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 即可。

    上面的效果为LayoutManager的方向为VERTICAL,那么接下来看一下横向效果,很简单,和上面的区别只是更改一下LayoutManager的方向,代码如下:


 LinearLayoutManager manager = new LinearLayoutManager(getContext());
 manager.setOrientation(LinearLayoutManager.HORIZONTAL);
 mRecyclerView.setLayoutManager(manager);
// 将SnapHelper attach 到RecyclrView
 LinearSnapHelper snapHelper = new LinearSnapHelper();
 snapHelper.attachToRecyclerView(mRecyclerView);

    简单几行代码就可以用RecyclerView 实现一个类似ViewPager的效果,并且效果更赞。可以快速滑动多页,当前页剧中显示,并且显示前一页和后一页的部分。如果使用ViewPager来做还是有点麻烦的。除了上面的效果外,如果你想要和ViewPager 一样,限制一次只让它滑动一页,那么你就可以使用PagerSnapHelper了。

(2) PagerSnapHelper (在Android 25.1.0 support 包加入的)
PagerSnapHelper的展示效果和LineSnapHelper是一样的,只是PagerSnapHelper 限制一次只能滑动一页,不能快速滑动。代码如下:

PagerSnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(mRecyclerView);

    此外,在Github上发现一个实现了好几种Snap 效果的库,比如,start对齐、end对齐,top 对齐等等。有兴趣的可以去弄来玩一下,地址:[Snap 效果库]。(https://github.com/rubensousa/RecyclerViewSnap)。

PS:有些同学发现自己item不能全屏,也就是match parent没有效果。问题在于在Adapter的onCreateViewHolder创建子view的时候要把parent传进去; 

正确写法

LayoutInflater.from(context).inflate(R.layout.item_view,parent,false);

错误写法

LayoutInflater.from(context).inflate(R.layout.item_view,null);

猜你喜欢

转载自my.oschina.net/zzxzzg/blog/1787619