wasabeef recyclerview recycler itemanimator item best animators animations android animation android-recyclerview

android - best - Cómo implementar ItemAnimator de RecyclerView para deshabilitar la animación de notifyItemChanged



recyclerview set item animator (7)

En mi proyecto, necesito deshabilitar la animación de "cambio" de RecyclerView mientras notifyItemChanged .

Investigué en la fuente de RecyclerView y había anulado android.support.v7.widget.DefaultItemAnimator siguiente manera:

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; } }

Pero no estoy seguro si coincido con la especificación del documento de Google: RecyclerView.ItemAnimator.animateChange

Según tengo entendido el código fuente, si no anulo el método correctamente, el oldHolder no se reciclará.

Por favor, ayúdame a descubrir cómo anular animateChange de la manera correcta.


He encontrado la solución correcta para eliminar animateChange.

Es muy sencillo. Google ha implementado la funcionalidad.

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

Documentación: setSupportsChangeAnimations


La respuesta de @Kenny ya no funcionó porque el método de eliminación de google setSupportsChangeAnimations() (pero ¿por qué?) En la biblioteca de soporte 23.1.0.

En algunos casos, setChangeDuration(0) puede funcionar como solución alternativa.

@edit Sugiero usar algo así:

RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator(); if (animator instanceof SimpleItemAnimator) { ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); }


La solución más fácil es extender DefaultItemAnimator y establecer setSupportsChangeAnimations en false correcto en el constructor:

public class DefaultItemAnimatorNoChange extends DefaultItemAnimator { public DefaultItemAnimatorNoChange() { setSupportsChangeAnimations(false); } }


Nada de las soluciones anteriores funcionó para mí. Lo que funcionó fue usar el TransitionManager y configurar la transición de la escena a nulo

TransitionManager.go(new Scene(recyclerView), null);

Para volver a habilitar la animación predeterminada, puede crear una nueva AutoTransition y configurarla con el mismo método anterior:

AutoTransition autoTransition = new AutoTransition(); TransitionManager.go(new Scene(recyclerView), autoTransition);


Si encuentra una solución, para todos los que quieran conservar todas las animaciones proporcionadas por DefaultItemAnimator, pero deshacerse de la animación de "parpadeo" que se produce cada vez que se actualiza la vista.

Primero, obtenga el código fuente de DefaultItemAnimator. Crea una clase con el mismo nombre en tu proyecto.

En segundo lugar, establezca el ItemAnimator en una nueva instancia de su DefaultItemAnimator modificado, de esta manera:

recyclerView.setItemAnimator(new MyItemAnimator());

Luego, vaya al código fuente de las nuevas clases y ubique el método

animateChangeImpl(final ChangeInfo changeInfo) { ... }

Ahora, simplemente tenemos que localizar las llamadas al método cambiando los valores alfa. Encuentre las siguientes dos líneas y elimine .alpha (0) y .alpha (1)

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

al igual que

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


Solo si alguien tropieza como yo:
De alguna manera, setSupportsChangeAnimations(false) no funcionó para mí, pero recyclerView.getItemAnimator().setChangeDuration(0) acaba de eliminar la animación.


Yo tuve el mismo problema. Al llamar a notifyItemChanged había una superposición roja parpadeando. Después de experimentar con su código, finalmente eliminé el Animator predeterminado simplemente llamando

recyclerView.setItemAnimator(null);

en el RecyclerView.