可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
In my project I need disable the "change" animation of RecyclerView
while notifyItemChanged
.
I investigated in the source of RecyclerView
and had overridden android.support.v7.widget.DefaultItemAnimator
as below:
private static class ItemAnimator extends DefaultItemAnimator
{
@Override
public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromX, int fromY, int toX, int toY) {
if(oldHolder != null)
{
oldHolder.itemView.setVisibility(View.INVISIBLE);
dispatchChangeFinished(oldHolder, true);
}
if(newHolder != null)
{
dispatchChangeFinished(newHolder, false);
}
return false;
}
}
But I am not sure if I match the spec of the Google document:
RecyclerView.ItemAnimator.animateChange
According to my understanding source code, if I do not override the method properly, the oldHolder will not be recycled.
Please help me figure out how to override animateChange
in a correct way.
回答1:
I have found the correct solution to just remove the animateChange.
It's very simple. Google has implemented the functionality.
((SimpleItemAnimator) RecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
Documentation: setSupportsChangeAnimations
回答2:
I had the same problem. When calling notifyItemChanged there was a red overlay flashing. After experimenting around with your code I finally removed the default Animator by simply calling
recyclerView.setItemAnimator(null);
on the RecyclerView.
回答3:
@Kenny answer didn't work anymore because google remove method setSupportsChangeAnimations()
(but why?) in support library 23.1.0.
In some case setChangeDuration(0)
can work as workaround.
@edit
I suggest use something like that:
RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator();
if (animator instanceof SimpleItemAnimator) {
((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
}
回答4:
If found a solution, for everyone who wants to keep all the animations given by the DefaultItemAnimator, but getting rid of the "blink" animation that occurs every time the view is updated.
First, get the source code of DefaultItemAnimator. Create a class with the same name in your project.
Second, set the ItemAnimator to a new instance of your modified DefaultItemAnimator, like so:
recyclerView.setItemAnimator(new MyItemAnimator());
Then, go in the new classes source code and locate the method
animateChangeImpl(final ChangeInfo changeInfo) { ... }
Now, 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() { ... }
回答5:
Just if someone stumbles like me:
Somehow setSupportsChangeAnimations(false)
didn't work for me, but recyclerView.getItemAnimator().setChangeDuration(0)
has just removed the animation nicely.
回答6:
The easiest solution is to extend DefaultItemAnimator
and set setSupportsChangeAnimations
to false
right in the constructor:
public class DefaultItemAnimatorNoChange extends DefaultItemAnimator {
public DefaultItemAnimatorNoChange() {
setSupportsChangeAnimations(false);
}
}
回答7:
I've created an Extention Class, to disable animation
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator
fun RecyclerView.disableAnimation() {
this.getItemAnimator()?.let {
if (it is SimpleItemAnimator) it.supportsChangeAnimations = false
}
}
You can call it like this:
recyclerView.disableAnimation()
回答8:
Nothing of the above solutions worked for me. What worked was using the TransitionManager and setting the scene transition to null
TransitionManager.go(new Scene(recyclerView), null);
To re-enable the default animation you can create a new AutoTransition and set it to the same method above:
AutoTransition autoTransition = new AutoTransition();
TransitionManager.go(new Scene(recyclerView), autoTransition);