Dans mon projet, il faut désactiver l'animation "change" de RecyclerView
tandis que notifyItemChanged
.
J'ai enquêté dans la source de RecyclerView
et j'avais écrasé Android.support.v7.widget.DefaultItemAnimator
comme ci-dessous:
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;
}
}
Mais je ne suis pas sûr de correspondre aux spécifications du document Google: RecyclerView.ItemAnimator.animateChange
D'après ce que je comprends du code source, si je ne substitue pas la méthode correctement, oldHolder ne sera pas être recyclé.
S'il vous plaît, aidez-moi à comprendre comment remplacer animateChange
de manière correcte.
J'ai trouvé la bonne solution pour supprimer simplement animateChange.
C'est très simple. Google a implémenté la fonctionnalité.
((SimpleItemAnimator) RecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
Documentation: setSupportsChangeAnimations
J'ai eu le même problème. Lors de l'appel de notifyItemChanged, un calque rouge clignotait. Après avoir expérimenté votre code, j'ai finalement supprimé l'animateur par défaut en appelant simplement
recyclerView.setItemAnimator(null);
sur le RecyclerView.
La réponse de @Kenny n'a plus fonctionné parce que la méthode de suppression de Google setSupportsChangeAnimations()
(mais pourquoi?) Dans la bibliothèque de support 23.1.0.
Dans certains cas, setChangeDuration(0)
peut fonctionner comme solution de contournement.
@edit je suggère d'utiliser quelque chose comme ça:
RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator();
if (animator instanceof SimpleItemAnimator) {
((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
}
Juste si quelqu'un trébuche comme moi:
D'une manière ou d'une autre setSupportsChangeAnimations(false)
n'a pas fonctionné pour moi, mais recyclerView.getItemAnimator().setChangeDuration(0)
vient de supprimer correctement l'animation.
Si trouvé une solution, pour tout le monde qui veut garder toutes les animations données par le DefaultItemAnimator, mais se débarrasser de l'animation "clignotant" qui se produit chaque fois que la vue est mise à jour.
Commencez par obtenir le code source de DefaultItemAnimator. Créez une classe avec le même nom dans votre projet.
Deuxièmement, définissez ItemAnimator sur une nouvelle instance de votre DefaultItemAnimator modifié, comme suit:
recyclerView.setItemAnimator(new MyItemAnimator());
Ensuite, allez dans le code source des nouvelles classes et localisez la méthode
animateChangeImpl(final ChangeInfo changeInfo) { ... }
Maintenant, nous devons simplement localiser les appels de méthodes qui changent les valeurs alpha. Recherchez les deux lignes suivantes et supprimez les fichiers .alpha (0) et .alpha (1)
oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() { ... }
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).alpha(1).setListener(new VpaListenerAdapter() { ... }
ainsi
oldViewAnim.setListener(new VpaListenerAdapter() { ... }
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).setListener(new VpaListenerAdapter() { ... }
La solution la plus simple consiste à étendre DefaultItemAnimator
et à définir setSupportsChangeAnimations
à false
directement dans le constructeur:
public class DefaultItemAnimatorNoChange extends DefaultItemAnimator {
public DefaultItemAnimatorNoChange() {
setSupportsChangeAnimations(false);
}
}