I am using Recyclerview with PageSnapHelper to create an Image carousel.
First item - Not Centered
The first Item is not centered and Subsequent Items should be centered, I have achieved this using item decorator. RecyclerView is inside nested scrollview.
Issue: Scrolling is not smooth, I have override findTargetSnapPosition, It is scrolling 2 items for the first fling.
override fun findTargetSnapPosition(layoutManager: RecyclerView.LayoutManager, velocityX: Int, velocityY: Int): Int {
if (layoutManager !is RecyclerView.SmoothScroller.ScrollVectorProvider) {
return RecyclerView.NO_POSITION
}
val currentView = findSnapView(layoutManager) ?: return RecyclerView.NO_POSITION
val layoutManager = layoutManager as LinearLayoutManager
val position1 = layoutManager.findFirstVisibleItemPosition()
val position2 = layoutManager.findLastVisibleItemPosition()
var currentPosition = layoutManager.getPosition(currentView)
if (velocityX > 500) {
currentPosition = position2
} else if (velocityX < 500) {
currentPosition = position1
}
return if (currentPosition == RecyclerView.NO_POSITION) {
RecyclerView.NO_POSITION
} else currentPosition
}
You can now just use a SnapHelper. If you want a center-aligned snapping behavior similar to ViewPager then use PagerSnapHelper: SnapHelper snapHelper = new PagerSnapHelper(); snapHelper. attachToRecyclerView(recyclerView);
SnapHelper is a helper class that helps in snapping any child view of the RecyclerView. For example, you can snap the firstVisibleItem of the RecyclerView as you must have seen in the play store application that the firstVisibleItem will be always completely visible when scrolling comes to the idle position.
SnapHelper is a helper class that is used to snap any child of our RecyclerView. With the help of this class, we can display the specific number of RecyclerView items on our screen, and we can avoid the RecyclerView children's display inside our RecyclerView.
If i got you right, you need to override LinearSnapHelper instead, cause your item views are not full screened. For achieving focusing on first/last items you need to override findSnapView next way(note that this snippet only applicable when RecyclerView.layoutmanager is LinearLayoutManager):
fun RecyclerView.setLinearSnapHelper(isReversed: Boolean = false) {
object : LinearSnapHelper() {
override fun findSnapView(layoutManager: RecyclerView.LayoutManager?): View? {
val firstVisiblePosition = (layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
val lastVisiblePosition = layoutManager.findLastCompletelyVisibleItemPosition()
val firstItem = 0
val lastItem = layoutManager.itemCount - 1
return when {
firstItem == firstVisiblePosition -> layoutManager.findViewByPosition(firstVisiblePosition)
lastItem == lastVisiblePosition -> layoutManager.findViewByPosition(lastVisiblePosition)
else -> super.findSnapView(layoutManager)
}
}
}.apply { attachToRecyclerView(this@setLinearSnapHelper) }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With