【问题标题】:Recyclerview withy LinearSnapHelper - snap to next item when release finger from the screenRecyclerview withy LinearSnapHelper - 当手指从屏幕上松开时捕捉到下一个项目
【发布时间】:2018-02-23 08:31:02
【问题描述】:

我已关注 this Stack Overflow post 创建具有 viewpager 行为的 recyclerview。

工作正常,但当用户抬起屏幕的手指时,我需要触发滚动到下一个项目。现在仅在 50% 可见时才捕捉到下一个项目。

更新解决方案

Crysxd 的响应是关键。为了检测捕捉方向,我在 findTargetSnapPosition 函数的顶部添加了以下代码:

if (velocityY < 0)
        snapToPrevious = true
else
        snapToNext = true

【问题讨论】:

标签: android android-recyclerview


【解决方案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 使用的实际速度无关紧要。

【讨论】:

  • 感谢您的回复。我会尽快检查并告诉你!!
  • 如果您有问题请告诉我,然后我可以更新我的回复
  • 嗨 Crysxd!效果很好。只有我添加了这段代码来检测捕捉方向: if (velocityY
猜你喜欢
  • 1970-01-01
  • 2019-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-22
相关资源
最近更新 更多