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.