0

我有水平滚动的recyclerview,默认情况下它使用LinearSnapHelper或PagerSnapHelper捕捉到项目的中心。我想捕捉到每个项目的左侧。可能吗?

4

1 回答 1

2

您可以轻松扩展 PagerSnapHelper 以在左侧对齐项目。只有最后一项才需要一个技巧。

我的解决方案是:

class AlignLeftPagerSnapHelper : PagerSnapHelper() {
private var horizontalHelper: OrientationHelper? = null

override fun findSnapView(layoutManager: RecyclerView.LayoutManager?): View? {
    return getStartView(layoutManager as LinearLayoutManager, getHorizontalHelper(layoutManager))
}

private fun getStartView(layoutManager: LinearLayoutManager, helper: OrientationHelper): View? {
    val firstVisibleChildPosition = layoutManager.findFirstVisibleItemPosition()
    val lastCompletelyVisibleChildPosition = layoutManager.findLastCompletelyVisibleItemPosition()
    val lastChildPosition = layoutManager.itemCount - 1

    if (firstVisibleChildPosition != RecyclerView.NO_POSITION) {
        var childView = layoutManager.findViewByPosition(firstVisibleChildPosition)
        if (helper.getDecoratedEnd(childView) < helper.getDecoratedMeasurement(childView) / 2) {
            childView = layoutManager.findViewByPosition(firstVisibleChildPosition + 1)
        } else if (lastCompletelyVisibleChildPosition == lastChildPosition) {
            childView = layoutManager.findViewByPosition(lastChildPosition)
        }
        return childView
    }
    return null
}

override fun calculateDistanceToFinalSnap(layoutManager: RecyclerView.LayoutManager, targetView: View): IntArray =
    intArrayOf(distanceToStart(targetView, getHorizontalHelper(layoutManager)), 0)

override fun findTargetSnapPosition(
    layoutManager: RecyclerView.LayoutManager,
    velocityX: Int,
    velocityY: Int
): Int {
    val currentView = findSnapView(layoutManager) ?: return RecyclerView.NO_POSITION
    val currentPosition = layoutManager.getPosition(currentView)

    return if (velocityX < 0) {
        (currentPosition - 1).coerceAtLeast(0)
    } else {
        (currentPosition + 1).coerceAtMost(layoutManager.itemCount - 1)
    }
}

private fun distanceToStart(targetView: View, helper: OrientationHelper): Int =
    helper.getDecoratedStart(targetView) - helper.startAfterPadding

private fun getHorizontalHelper(layoutManager: RecyclerView.LayoutManager): OrientationHelper {
    if (horizontalHelper == null) {
        horizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager)
    }
    return horizontalHelper!!
}

}

于 2021-02-02T17:07:48.637 回答