Skip to content

Instantly share code, notes, and snippets.

@orioonyx
Created January 8, 2023 14:23
Show Gist options
  • Select an option

  • Save orioonyx/08da61c1145c70bcc28eea2bcb42ef4d to your computer and use it in GitHub Desktop.

Select an option

Save orioonyx/08da61c1145c70bcc28eea2bcb42ef4d to your computer and use it in GitHub Desktop.
RecyclerView Custom LayoutManager to centrally zoom items.
class CenterZoomLayoutManager : LinearLayoutManager {
private var mShrinkAmount = 0.1f
private val mShrinkDistance = 0.9f
constructor(context: Context?, orientation: Int, reverseLayout: Boolean, shrinkAmount: Float) : super(
context,
orientation,
reverseLayout
) {
mShrinkAmount = shrinkAmount
}
override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams {
return RecyclerView.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
override fun canScrollHorizontally(): Boolean {
return true
}
override fun scrollHorizontallyBy(dx: Int, recycler: Recycler, state: RecyclerView.State): Int {
val orientation = orientation
return if (orientation == HORIZONTAL) {
val scrolled = super.scrollHorizontallyBy(dx, recycler, state)
val midpoint = width / 2f
val d0 = 0f
val d1 = mShrinkDistance * midpoint
val s0 = 1f
val s1 = 1f - mShrinkAmount
for (i in 0 until childCount) {
val child = getChildAt(i)
val childMidpoint = (getDecoratedRight(child!!) + getDecoratedLeft(
child
)) / 2f
val d = min(d1, abs(midpoint - childMidpoint))
val scale = s0 + (s1 - s0) * (d - d0) / (d1 - d0)
child.scaleX = scale
child.scaleY = scale
}
scrolled
} else {
0
}
}
override fun smoothScrollToPosition(
recyclerView: RecyclerView,
state: RecyclerView.State,
position: Int
) {
val linearSmoothScroller: LinearSmoothScroller =
object : LinearSmoothScroller(recyclerView.context) {
override fun computeScrollVectorForPosition(targetPosition: Int): PointF? {
// Calculate the scroll vector for the target position
return super.computeScrollVectorForPosition(targetPosition)
}
override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float {
// Calculate the speed at which the RecyclerView should scroll
return 0.1f / displayMetrics.densityDpi
}
}
linearSmoothScroller.targetPosition = position
startSmoothScroll(linearSmoothScroller)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment