Cómo implementar ItemAnimator de RecyclerView para deshabilitar la animación de notifyItemChanged
En mi proyecto necesito desactivar la animación de "cambio" de RecyclerView
mientras notifyItemChanged
.
Investigué en la fuente de RecyclerView
y había anulado android.support.v7.widget.DefaultItemAnimator
como abajo:
- Cómo filtrar un RecyclerView con un SearchView
- Android Recyclerview Layoutmanager's onLayoutChildren llamado cuando se cambia el contenido del elemento
- Implementar el gesto de deslizamiento en un elemento de RecyclerView?
- Android notifyItemRangeInserted deshabilitar autoscroll
- AdView adjunto al fondo no me permite ver el último elemento en Recyclerview
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 las especificaciones del documento de Google: RecyclerView.ItemAnimator.animateChange
De acuerdo con mi código fuente de comprensión, si no reemplazo el método correctamente, el oldHolder no será reciclado.
Por favor, ayúdame a averiguar cómo anular animateChange
de una manera correcta.
- Recyclerview automáticamente se desplaza hacia arriba cuando los datos insertados
- Optimización de RecyclerView / ListView
- RecyclerView vs. ListView
- RecyclerView onClick
- Implementar una vista ampliable Android Recycler con encabezados pegajosos, función de búsqueda, selector lateral alfabético y Swipable Items / tarjetas?
- Disposición de Android: Recyclerview horizontal dentro de una Recyclerview vertical dentro de un Viewpager con comportamientos de desplazamiento
- Cuándo usar ListView en lugar de RecyclerView
- Los elementos de RecyclerView desaparecen después de cambiar entre fragmentos
He encontrado la solución correcta para eliminar el animateChange.
Es muy sencillo. Google ha implementado la funcionalidad.
((SimpleItemAnimator) RecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
Documentación: setSupportsChangeAnimations
Yo tuve el mismo problema. Al llamar a notifyItemChanged había una superposición roja parpadeando. Después de experimentar alrededor con su código finalmente quité el animador del defecto llamando simplemente
recyclerView.setItemAnimator(null);
En el RecyclerView.
@Kenny respuesta no funcionó más porque google remove método setSupportsChangeAnimations()
(pero ¿por qué?) En la biblioteca de soporte 23.1.0.
En algunos casos setChangeDuration(0)
puede funcionar como solución.
@edit Sugiero utilizar algo como eso:
RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator(); if (animator instanceof SimpleItemAnimator) { ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); }
Si encuentra una solución, para todos los que quieran mantener todas las animaciones dadas por el DefaultItemAnimator, pero deshacerse de la "parpadeo" de animación que se produce cada vez que se actualiza la vista.
En primer lugar, obtener el código fuente de DefaultItemAnimator. Cree una clase con el mismo nombre en su proyecto.
En segundo lugar, establezca el ItemAnimator a una nueva instancia de su DefaultItemAnimator modificado, así:
recyclerView.setItemAnimator(new MyItemAnimator());
A continuación, vaya al código fuente de las nuevas clases y localice el método
animateChangeImpl(final ChangeInfo changeInfo) { ... }
Ahora, simplemente tenemos que localizar las llamadas al método cambiando valores alfa. Encuentre las dos líneas siguientes y elimine los valores de α (0) y α (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() { ... }
Sólo 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 muy bien.
La solución más fácil es extender DefaultItemAnimator
y establecer setSupportsChangeAnimations
a false
en el constructor:
public class DefaultItemAnimatorNoChange extends DefaultItemAnimator { public DefaultItemAnimatorNoChange() { setSupportsChangeAnimations(false); } }