How to use object animator for background color of items in RecyclerView?

37 Views Asked by At

I have a RecyclerView where some items should have their background color change animatedly from pink to transparent for 6 seconds when they appear on the screen.

But the problem is that in addition to those items whose background color should change, until the 6 seconds of animation of the main items is finished, the background color of some other items will also change. And when 6 seconds are over, the background color of all items will be transparent.

   override fun onBindViewHolder(holder: Holder, position: Int) {
        val item = getItem(position)

        if (item.hasFade) {
            item.hasFade = false
            val colorFade = ObjectAnimator.ofObject(holder.itemView, "backgroundColor", ArgbEvaluator(), 0x32E91E63, Color.TRANSPARENT)
            colorFade.duration = 6000L
            colorFade.start()
        } else {
            itemView.background = null
        }
    }
2

There are 2 best solutions below

0
Moataz On

The problem that you are facing is when a ViewHolder is recycled, it retains the properties of the item it was previously used for, So, if an item that required the animation was bound to a ViewHolder, and then this ViewHolder was recycled for an item that does not require the animation, it would still show the animation.

So, to fix this, you need to ensure that you reset the background color of the itemView in the else block of your onBindViewHolder method.

Your code should look something like this:

override fun onBindViewHolder(holder: Holder, position: Int) {
val item = getItem(position)

if (item.hasFade) {
    item.hasFade = false
    val colorFade = ObjectAnimator.ofObject(holder.itemView, "backgroundColor", ArgbEvaluator(), 0x32E91E63, Color.TRANSPARENT)
    colorFade.duration = 6000L
    colorFade.start()
} else {
    holder.itemView.setBackgroundColor(Color.TRANSPARENT)
   }
}
0
BochenChleba On

RecyclerView items are reused when you are scrolling. Please try to call holder.setIsRecyclable(false) at the beginning of onBindViewHolder method to prevent reusing item. Then add listener to your animation (colorFade.addListener) and override onAnimationEnd method in listener. Inside it call holder.setIsRecyclable(true) to allow item to be recycled when animation is finished.