Shrinkin/growing ViewPager

When iOS-ifying a ViewPager, it is often needed to animate the pages when they come into view. The following snippet shrinks the offscreen pages a little bit, and grows them to regular size when swiping them to the center of the display.

Use this snippet by setting it as a PageTransformer like so:

viewpager.setPageTransformer(ScalingPageTransformer())

Here’s the transformer:

class ScalingPageTransformer : ViewPager.PageTransformer {

    companion object {
        private val MAX_MARGIN = 24.px
    }

    override fun transformPage(view: View, position: Float) {
        when {
            position < -1 -> // [-Infinity,-1)
                // This page is way off-screen to the left.
                setScale(view, 0f)
            position <= 1 -> { // [-1,1]
                // Modify the default slide transition to shrink the page as well
                val scaleFactor = 1 - Math.abs(position)
                setScale(view, scaleFactor)
            }
            else -> // (1,+Infinity]
                // This page is way off-screen to the right.
                setScale(view, 0f)
        }
    }

    private fun setScale(view: View, scaleFactor: Float) {
        val padding = ((1f - scaleFactor) * MAX_MARGIN).toInt()
        view.setPadding(padding / 2, padding, padding / 2, padding)
        view.requestLayout()
    }
}

Note that this snippet is compatible with infinitely looping viewpagers, hence the support for negative positions.

This extension method is used, though of course, you should really be getting this margin from the resources instead.

val Int.px: Int
    get() = (this * Resources.getSystem().displayMetrics.density).toInt()