UgAr0FF 的解决方案通常有效,但也会导致不需要的滚动行为:
它不应该看起来如何
如您所见,PagerSnapHelper 首先尝试关注分隔线,然后决定移动到下一项。我修复了滚动行为,使其看起来像这样:
它应该是什么样子
这是代码:
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_SETTLING
class PagerSnapAndSkipDividerHelper : PagerSnapHelper() {
private var dx = 0
override fun attachToRecyclerView(recyclerView: RecyclerView?) {
super.attachToRecyclerView(recyclerView)
recyclerView?.addOnScrollListener(onScrollListener)
}
override fun findTargetSnapPosition(
layoutManager: RecyclerView.LayoutManager?,
velocityX: Int,
velocityY: Int
): Int = getNextNonDividerPosition(
super.findTargetSnapPosition(layoutManager, velocityX, velocityY)
)
private fun getNextNonDividerPosition(position: Int) =
if (position % 2 == 0) position else if (dx > 0) position + 1 else position - 1
private val onScrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
this@PagerSnapAndSkipDividerHelper.dx = dx
}
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
if (listOf(SCROLL_STATE_IDLE, SCROLL_STATE_SETTLING).contains(newState)) {
val viewToSnapTo = findSnapView(recyclerView.layoutManager) ?: return
val position = recyclerView.layoutManager?.getPosition(viewToSnapTo) ?: return
val nonDividerPosition = getNextNonDividerPosition(position)
if (position != nonDividerPosition) {
recyclerView.smoothScrollToPosition(nonDividerPosition)
}
}
}
}
}
像这样设置它:
PagerSnapAndSkipDividerHelper().attachToRecyclerView(recyclerView)