Override animation for notifyItemChanged in RecyclerView.Adapter

AndroidAndroid Recyclerview

Android Problem Overview


Well, I have a RecyclerView with an adapter and everything works great. The items in the ArrayList dataset are being updated periodically. So the items and their elements as well as their position in the list change. This is achieved by simple sorting and manually calling these methods, whenever things happen:

// swapping two items
Collections.swap(items, i, j);
itemsAdapter.notifyItemMoved(i, j);

// adding a new one
itemAdapter.notifyItemInserted(items.size());

// when updating valus
itemAdapter.notifyItemChanged(i);

The latter of which, is the cause of my misery. Every time an item is updated, a little "blink" animation is triggered.

I found a couple of solutions for this:

// disabling all animations
recyclerView.getItemAnimator().setSupportsChangeAnimations(false);

// or

// setting the animation duration to zero,
recyclerView.getItemAnimator().setChangeDuration(0);

But both of these kill the animations when items move (being swapped). I just want to override the one animation and keep all of this magic. Is there a way of doing this? And if it's overriding ItemAnimator, does anyone have a simple example?

Thanks in advance!

Android Solutions


Solution 1 - Android

There is a dedicated method to disable just item changed animations:

((SimpleItemAnimator) myRecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);

Official docs.

Solution 2 - Android

Yes, I did.

First, get the source code of DefaultItemAnimator. Take the code and create a class named MyItemAnimator in your project. Then, set the ItemAnimator to a new instance of your modified MyItemAnimator, like so:

recyclerView.setItemAnimator(new MyItemAnimator());

Now, go in the new classes source code and locate the method

animateChangeImpl(final ChangeInfo changeInfo) { ... }

We simply have to locate the method calls changing alpha values. Find the following two lines and remove the .alpha(0) and .alpha(1)

oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() { ... }
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).alpha(1).setListener(new VpaListenerAdapter() { ... }

like so

oldViewAnim.setListener(new VpaListenerAdapter() { ... }
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).setListener(new VpaListenerAdapter() { ... }

Solution 3 - Android

Try setting:

mRecyclerview.setItemAnimator(null);

Solution 4 - Android

Kotlin version of @Pablo A. Martínez answer:

(recyclerView.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false

Solution 5 - Android

If you are only modifying the data of Recyclerview means no addition or deletion of item then you should add this line.

mRecyclerview.setHasFixedSize(true); 

So that recyclerview will get to know there is no change in size after that you can apply

((SimpleItemAnimator) mRecyclerview.getItemAnimator()).setSupportsChangeAnimations(false);

So that animation will be disappear and code will work like charm :)

Solution 6 - Android

Slight variation on Alex's answer.

Instead of removing the alpha change altogether, I just reduced it. the only changes needed were:

        //changed alpha from 0
        ViewCompat.setAlpha(newHolder.itemView, 0.5f);

and

        //changed alpha from 0
        oldViewAnim.alpha(0.5f).setListener(new VpaListenerAdapter() {

In both cases, change the 0 to 0.5 This has the effect of removing the flicker associated with the alpha going completely to 0, but keeps the morphing qualities of the item change animation.

Solution 7 - Android

In my case the recyclerview took all the space below toolbar. All I did was changing the layout_height of recyclerview from wrap_content to match_parent and blinking disappeared.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlexView Question on Stackoverflow
Solution 1 - AndroidPablo A. MartínezView Answer on Stackoverflow
Solution 2 - AndroidAlexView Answer on Stackoverflow
Solution 3 - AndroidboxView Answer on Stackoverflow
Solution 4 - AndroidMBHView Answer on Stackoverflow
Solution 5 - AndroidKeyur LakhaniView Answer on Stackoverflow
Solution 6 - AndroidDeeferView Answer on Stackoverflow
Solution 7 - AndroidCode4FunView Answer on Stackoverflow