Disable RecyclerView child sizing animation

I have a view and I want to resize it when clicked.

I have the following layout for the test:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <pro.labster.coloringbook.ui.view.ColorView
        android:id="@+id/colorView"
        android:layout_width="@dimen/colorSize"
        android:layout_height="@dimen/colorSize"
        android:layout_centerInParent="true"
        app:normalSize="@dimen/colorSize"
        app:selectedSize="@dimen/selectedColorSize" />

</RelativeLayout>

And the following code:

val colorView = findViewById<ColorView>(R.id.colorView)
colorView.setBackgroundColor(Color.RED)
colorView.setOnClickListener {
    isSelected = !isSelected
    colorView.setColorSelected(isSelected)
}

Resize Code:

fun setColorSelected(isSelected: Boolean) {
        if (isColorSelected != isSelected) {
            if (isSelected) {
                setCurrentSize(selectedSize.toInt())
            } else {
                setCurrentSize(normalSize.toInt())
            }
        }

        isColorSelected = isSelected
    }

private fun setCurrentSize(size: Int) {
    if (layoutParams.height != size || layoutParams.width != size) {
        layoutParams.width = size
        layoutParams.height = size
        requestLayout()
    }
}

It works well:

https://www.youtube.com/watch?v=Ft8xcX5Qxbg

But if I add this view to the RecyclerView, it will lag behind resizing:

class ColorsAdapter(colorsHex: List<String>) : RecyclerView.Adapter<ColorsAdapter.ViewHolder>() {

    private val colors = mutableListOf<Int>()
    private var selectedPosition: Int = 0

    init {
        colorsHex.forEach {
            colors.add(Color.parseColor(it))
        }
    }

    override fun getItemCount() = colors.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val color = colors[position]

        holder.colorView.setBackgroundColor(color)
        holder.colorView.tag = position

        holder.colorView.setColorSelected(position == selectedPosition)
    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
        val inflater = LayoutInflater.from(parent?.context)

        val view = inflater.inflate(R.layout.view_item_color, parent, false)

        return ViewHolder(view)
    }


    inner class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView) {
        val colorView: ColorView = itemView!!.findViewById(R.id.colorView)

        init {
            colorView.setOnClickListener {
                val oldPosition = selectedPosition

                selectedPosition = colorView.tag as Int

                if (oldPosition != selectedPosition) {
                    notifyItemChanged(oldPosition)
                    notifyItemChanged(selectedPosition)
                }
            }
        }
    }

}

view_item_color.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="@dimen/selectedColorSize"
    android:layout_height="@dimen/selectedColorSize">

    <pro.labster.coloringbook.ui.view.ColorView
        android:id="@+id/colorView"
        android:layout_width="@dimen/colorSize"
        android:layout_height="@dimen/colorSize"
        android:layout_gravity="center"
        app:normalSize="@dimen/colorSize"
        app:selectedSize="@dimen/selectedColorSize" />

</FrameLayout>

https://www.youtube.com/watch?v=m8g6zpj9aDg

As I can see, he is also trying to animate resizing - is that true?

And how to fix this lag?

+4
source share
3 answers

As seen from the docsDefaultItemAnimator :

RecyclerView.ItemAnimator , , RecyclerView. RecyclerView DefaultItemAnimator.

, :

recyclerview.itemAnimator = null
+2

notifyItemChanged(position: Int), RecyclerView , - , , ViewHolder onBindViewHolder(holder: ViewHolder, position:Int) , .

, , notifyItemChanged(position: Int, payload: Any) , RecyclerView ViewHolder onBindViewHolder(holder: ViewHolder, position:Int, payloads: MutableList<Any>) .

, ViewHolder:

init {
    colorView.setOnClickListener {
    val oldPosition = selectedPosition

    selectedPosition = colorView.tag as Int

    if (oldPosition != selectedPosition) {
       notifyItemChanged(oldPosition, false)   // include payloads
       notifyItemChanged(selectedPosition, true)
       }
    }
}

:

override fun onBindViewHolder(holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
    if(payloads.size < 1){
        //if there are no payloads perform full binding
        onBindViewHolder(holder, position)
        return
    }
    // if viewHolder can consume incremental updates iterate over payloads
    // otherwise it enough to grab the last update
    // cast as Boolean is safe because only Booleans are passed as payloads
    holder.colorView.setColorSelected(payloads.last() as Boolean)
}

, ViewHolders ( onViewRecycled(holder: ViewHolder) / )

0

You can do this with the Item Animator and initialize the item animator.

-1
source

Source: https://habr.com/ru/post/1692162/


All Articles