簡(jiǎn)介
在列表滑動(dòng)瀏覽惧所,有時(shí)希望當(dāng)滑動(dòng)停止某個(gè) ItemView
時(shí)可以停留在屏幕中央吸引用戶的焦點(diǎn)骤坐,或者在邊緣顯示半個(gè)提示用戶還有更多內(nèi)容。RecyclerView在24.2.0版本中新增了SnapHelper這個(gè)輔助類來(lái)實(shí)現(xiàn)該效果下愈。
SnapHelper 是個(gè)抽象類纽绍,在25.1.+版本官方提供了 ItemView 停留在中間位置的實(shí)現(xiàn) LinearSnapHeler
,和類似于 ViewPager 效果的PageSnapHelper
原理
首先來(lái)張圖
SnapHelper的主作用就是尋找離目標(biāo)位置最近的ItemView作為SnapView并滑動(dòng)到目標(biāo)位置。
SnapHelper類提供了三個(gè)抽象方法势似,方便子類實(shí)現(xiàn)不同的對(duì)齊效果:
查找當(dāng)前離目標(biāo)最近的ItemView
public abstract View findSnapView(LayoutManager layoutManager);
根據(jù)加速度返回需要對(duì)齊ItemView的位置拌夏,主要用于fling 操作
public abstract int findTargetSnapPosition(LayoutManager layoutManager, int velocityX,
int velocityY)
返回targetView 對(duì)齊到指定目標(biāo)位置的x,y軸上的偏移量。
public abstract int[] calculateDistanceToFinalSnap(@NonNull LayoutManager layoutManager,
@NonNull View targetView)
與RecyclerView交互
在 SnapHelper.attachToRecyclerView()
方法中調(diào)用了 RecyclerView.addOnScrollListener() 和RecyclerView.setOnFlingListener()兩個(gè)方法監(jiān)聽RecyclerView的滑動(dòng)事件履因。
- recycleView 滑動(dòng)則OnScrollListener收到回調(diào)辖佣,滑動(dòng)停止后調(diào)用
SnapHelper.snapToTargetExistingView()
尋找SnapView 計(jì)算對(duì)齊對(duì)目標(biāo)位置的位移量,調(diào)用RecyclerView.smoothScrollBy()方法對(duì)齊搓逾。
- recyclerView 有Fling操作則OnFlingListener收到回調(diào),并調(diào)用
SnapHelper.snapFromFling()
,根據(jù)加速度計(jì)算將要對(duì)齊的ItemView 的位置杯拐,利用LinearSmoothScroller
進(jìn)行平滑滾動(dòng)對(duì)齊操作霞篡。
相關(guān)知識(shí)點(diǎn)
-
fling操作時(shí)平滑滾到到目標(biāo)位置世蔗。
LinearSmoothScroller一般只是把目標(biāo)targetPosition移到recyclerView的邊緣±时可重寫方法以到到想要的效果污淋。
OrientationHelper.createHorizontalHelper(layoutManager)可用于計(jì)算recyclerview中的Item的位置。
遺留問(wèn)題
- 對(duì)齊太快余掖,但是recyclerview也沒(méi)有提供公開方法用于指定滑動(dòng)距離的時(shí)間和差值器寸爆。