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

本文介绍了如何在Android中利用RecyclerView结合SnapHelper实现类似ViewPager的滑动效果。通过LinearSnapHelper和PagerSnapHelper的使用方法及示例,展示了如何让当前Item居中显示。同时,文章还探讨了SnapHelper的源码分析和自定义SnapHelper以实现不同对齐方式的技巧。
摘要由CSDN通过智能技术生成

1

 前言

一些特定的场景下,如照片的浏览,卡片列表滑动浏览,我们希望当滑动停止时可以将当前的照片或者卡片停留在屏幕中央,以吸引用户的焦点。在 Android 中,我们可以使用RecyclerView + Snaphelper 来实现,SnapHelper 旨在支持 RecyclerView 的对齐方式,也就是通过计算对齐 RecyclerView 中 TargetView 的指定点或者容器中的任何像素点(包括前面说的显示在屏幕中央)。本篇文章将详细介绍 SnapHelper 的相关知识点。本文目录如下:



2

 SnapHelper 介绍

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



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 内置了两个默认实现类,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 即可。

效果如下:


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

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

PagerSnapHelper snapHelper = new PagerSnapHelper();

snapHelper.attachToRecyclerView(mRecyclerView);

PagerSnapHelper效果如下:


上面展示的是 PagerSnapHelper 水平方向的效果,竖直方向的效果和 LineSnapHelper 竖直的方向的效果差不多,只是不能快速滑动,就不在介绍了,感兴趣的可以把它们的效果都试一下。

上面就是LineSnapHelper和 PagerSnapHelper的使用和效果展示,了解了它的使用方法和效果,接下来我们看一下它的实现原理。

4

 SnapHelper原码分析

上面介绍了 SnapHelper 的使用,那么接下来我们来看一下 SnapHelper 到底是怎么实现的,走读一下源码:

(1) 入口方法,attachToRecyclerView
通过
attachToRecyclerView方法将 SnapHelper attach 到 RecyclerView,看一下这个方法做了哪些事情:

    /**
*
* 1,首先判断attach的RecyclerView 和原来的是否是一样的,一样则返回,不一样则替换
*
* 2,如果不是同一个RecyclerView,将原来设置的回调全部remove或者设置为null
*
   * 3,Attach的RecyclerView不为null,先2设置回调 滑动的回调和Fling操作的回调,

* 初始化一个Scroller 用于后面做滑动处理,然后调用snapToTargetExistingView
*
* */ public void attachToRecyclerView(@Nullable RecyclerView recyclerView) throws IllegalStateException { if (mRecyclerView == recyclerView) { return; // nothing to do } if (mRecyclerView != null) { destroyCallbacks(); } mRecyclerView = recyclerView;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值