我已按照this Stack Overflow post创建了一个包含viewpager行为的recyclerview。
工作正常,但是当用户抬起屏幕的手指时,我需要触发滚动到下一个项目。现在只有在50%可见时才会捕捉到下一个项目。
更新解决方案
Crysxd的回应是关键。为了检测捕捉方向,我将此代码添加到findTargetSnapPosition函数的顶部:
if (velocityY < 0)
snapToPrevious = true
else
snapToNext = true
答案 0 :(得分:1)
无法围绕自定义SnapHelper。这是一个您可以复制到项目中的类。
class ControllableSnapHelper(val onSnapped: ((Int) -> Unit)? = null) : LinearSnapHelper() {
var snappedPosition = 0
private var snapToNext = false
private var snapToPrevious = false
var recyclerView: RecyclerView? = null
override fun attachToRecyclerView(recyclerView: RecyclerView?) {
super.attachToRecyclerView(recyclerView)
this.recyclerView = recyclerView
}
override fun findTargetSnapPosition(layoutManager: RecyclerView.LayoutManager, velocityX: Int, velocityY: Int): Int {
if (snapToNext) {
snapToNext = false
snappedPosition = Math.min(recyclerView?.adapter?.itemCount ?: 0, snappedPosition + 1)
} else if (snapToPrevious) {
snapToPrevious = false
snappedPosition = Math.max(0, snappedPosition - 1)
} else {
snappedPosition = super.findTargetSnapPosition(layoutManager, velocityX, velocityY)
}
onSnapped?.invoke(snappedPosition)
return snappedPosition
}
fun snapToNext() {
snapToNext = true
onFling(Int.MAX_VALUE, Int.MAX_VALUE)
}
fun snapToPrevious() {
snapToPrevious = true
onFling(Int.MAX_VALUE, Int.MAX_VALUE)
}
}
您也可以将LinearSnapHelper
替换为PagerSnapHelper
。只需致电snapToNext()
或snapToPrevious()
。我还实现了在构造函数中传递的回调。
我们只是覆盖findTargetSnapPosition(...)
方法。此方法可以返回任何位置,然后SnapHelper
实现将计算滚动动画以到达该位置。函数snapToNext()
和snapToPrevious()
只是设置了一个布尔值,告诉我们下次调用findTargetSnapPosition(...)
时捕捉到下一个或上一个视图。添加snapTo(index: Int)
函数也非常简单。设置布尔值后,我们需要启动快照进度。为此,我们调用onFling(...)
,当用户移动RecyclerView
时会调用它。我们需要传递一个超过SnapHelper
设置的最小速度的值,因此我们只使用Int.MAX_VALUE
。由于我们从不称之为super.findTargetSnapPosition(...)
,因此PagerSnapHelper
使用的实际速度并不重要。