简体   繁体   中英

How to snap to the left side of the item in RecyclerView

I have recyclerview with horizontal scroll and it snaps by default with LinearSnapHelper or PagerSnapHelper to the center of item. I want to snap to the left side of the each item. Is it possible?

You can easily extend PagerSnapHelper to align items by left side. There is one trick only needed with last item.

My solution is:

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!!
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM