안드로이드

안드로이드 RecyclerView focused Item zoomIn FocusedItemZoomLayoutManager

알통몬_ 2021. 4. 2. 17:16
반응형

RecyclerView 사용 시 focus 된 item을 확대하는 애니메이션을 준다.

LinearLayoutManager를 상속받아서 커스텀한다.

import android.content.Context
import android.util.Log
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlin.math.abs
import kotlin.math.min

class FocusedItemZoomLayoutManager(
    context: Context,
    orientation: Int? = 0,
    reverseLayout: Boolean? = false
): LinearLayoutManager(context, orientation!!, reverseLayout!!) {

    private val amount = 0.15f
    private val distance = 0.9f

    override fun onLayoutCompleted(state: RecyclerView.State?) {
        super.onLayoutCompleted(state)
        scaling()
    }

    override fun scrollHorizontallyBy(
        dx: Int,
        recycler: RecyclerView.Recycler?,
        state: RecyclerView.State?
    ) =  if(orientation == HORIZONTAL) {
            super.scrollHorizontallyBy(dx, recycler, state).also { scaling() }
        } else {
            0
        }

    private fun scaling() {
        val midPoint = width / 2f
        val d0 = 0.0f
        val d1 = distance * midPoint
        val s0 = 1.0f
        val s1 = 1.0f - amount
        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)
            Log.e("scale value", "$scale")
            child.isEnabled = scale > (0.9f - amount)
            child.scaleX = scale
            child.scaleY = scale
        }
    }
}
반응형