一、需求简介
项目需要实现一个垂直滑动画廊效果的鸡汤App,因为之前做过左右侧滑的壁纸App,使用的是ViewPager来实现的,但是这个App就想到了列表来实现。
二、实现方法
因为画廊效果的每一个子项Item是全屏的,最开始想的是监听用户的手势,滑动到一定的距离时,切换到下一个/上一个Item,但是监听的事件有冲突,我在下滑的时候很难切到上一个Item,于是乎我就在想RecycleView有没有自带的接口去实现,没想到还真被我找到了:SnapHelper
SnapHealper 介绍
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。
三、实现代码
这儿我用的是PagerSnapHelper(一次只能滑动一页)
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
recyclerView.adapter = GalleryAdapter(yourDataList)//并不是什么特殊的Adapter
// 使用PagerSnapHelper来实现分页滚动效果
val pagerSnapHelper = PagerSnapHelper()
pagerSnapHelper.attachToRecyclerView(recyclerView)
tips:
LinearSnapHelper:
使当前Item居中显示,常用场景是横向/纵向的RecyclerView, 类似ViewPager效果,但是又可以快速滑动(滑动多页)PagerSnapHelper:
PagerSnapHelper的展示效果和LineSnapHelper是一样的,只是PagerSnapHelper 限制一次只能滑动一页,不能快速滑动。