Cómo animar la adición o la eliminación de Android ListView filas

En iOS, hay una facilidad muy fácil y poderosa para animar la adición y eliminación de filas UITableView, aquí hay un clip de un video de youtube que muestra la animación predeterminada. Observe cómo las filas circundantes se colapsan en la fila eliminada. Esta animación ayuda a los usuarios a realizar un seguimiento de lo que cambió en una lista y de la lista en la que estaban viendo cuando los datos cambiaron.

Desde que he estado desarrollando en Android no he encontrado ninguna instalación equivalente para animar filas individuales en un TableView . Llamar notifyDataSetChanged() en mi adaptador hace que ListView actualice inmediatamente su contenido con nueva información. Me gustaría mostrar una animación simple de una nueva fila empujando o deslizando hacia fuera cuando los datos cambian, pero no puedo encontrar ninguna manera documentada de hacer esto. Parece que LayoutAnimationController puede contener una clave para que esto funcione, pero cuando establezco un LayoutAnimationController en mi ListView (similar a LayoutAnimation2 de ApiDemo ) y elimino elementos de mi adaptador después de que se muestre la lista, los elementos desaparecen inmediatamente en lugar de obtener animated out .

También he intentado cosas como las siguientes para animar un elemento individual cuando se elimina:

 @Override protected void onListItemClick(ListView l, View v, final int position, long id) { Animation animation = new ScaleAnimation(1, 1, 1, 0); animation.setDuration(100); getListView().getChildAt(position).startAnimation(animation); l.postDelayed(new Runnable() { public void run() { mStringList.remove(position); mAdapter.notifyDataSetChanged(); } }, 100); } 

Sin embargo, las filas que rodean la fila animada no se mueven hasta que salten a sus nuevas posiciones cuando se llama notifyDataSetChanged() . Parece que ListView no actualiza su diseño una vez que se han colocado sus elementos.

Mientras escribo mi propia implementación / tenedor de ListView ha cruzado mi mente, esto parece algo que no debería ser tan difícil.

¡Gracias!

 Animation anim = AnimationUtils.loadAnimation( GoTransitApp.this, android.R.anim.slide_out_right ); anim.setDuration(500); listView.getChildAt(index).startAnimation(anim ); new Handler().postDelayed(new Runnable() { public void run() { FavouritesManager.getInstance().remove( FavouritesManager.getInstance().getTripManagerAtIndex(index) ); populateList(); adapter.notifyDataSetChanged(); } }, anim.getDuration()); 

Para el uso de animación de arriba a abajo:

 <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromYDelta="20%p" android:toYDelta="-20" android:duration="@android:integer/config_mediumAnimTime"/> <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="@android:integer/config_mediumAnimTime" /> </set> 

¡El RecyclerView se encarga de agregar, quitar y reordenar animaciones!

RecyclerView en acción

Este sencillo proyecto de AndroidStudio cuenta con un RecyclerView . Eche un vistazo a los compromisos :

  1. Confirmación de la clásica aplicación Android de Hello World
  2. Commit, añadiendo un RecyclerView al proyecto (contenido no dinámico)
  3. Commit, añadiendo funcionalidad para modificar el contenido de RecyclerView en tiempo de ejecución (pero sin animaciones)
  4. Y finalmente … cometer añadir animaciones al RecyclerView

Echa un vistazo a la solución de Google. Este es un método de eliminación solamente.

ListViewRemovalAnimation proyecto de código y demostración de vídeo

Necesita Android 4.1 o superior (API 16). Pero tenemos 2014 afuera.

Desde ListViews son altamente optimizado creo que esto no es posible accieve. ¿Ha intentado crear su "ListView" por código (es decir, inflando sus filas de xml y añadiéndolas a un LinearLayout ) y animarlos?

¿Has considerado animar un barrido a la derecha? Podrías hacer algo como dibujar una barra blanca progresivamente más grande en la parte superior del elemento de la lista y luego eliminarla de la lista. Las otras células aún se sacudían en su lugar, pero sería mejor que nada.

Llamada listView.scheduleLayoutAnimation (); Antes de cambiar la lista

He hackeado juntos otra manera de hacerlo sin tener que manipular la vista de lista. Desafortunadamente, las animaciones regulares de Android parecen manipular el contenido de la fila, pero son ineficaces al reducir la vista. Por lo tanto, primero considere este manejador:

 private Handler handler = new Handler() { @Override public void handleMessage(Message message) { Bundle bundle = message.getData(); View view = listView.getChildAt(bundle.getInt("viewPosition") - listView.getFirstVisiblePosition()); int heightToSet; if(!bundle.containsKey("viewHeight")) { Rect rect = new Rect(); view.getDrawingRect(rect); heightToSet = rect.height() - 1; } else { heightToSet = bundle.getInt("viewHeight"); } setViewHeight(view, heightToSet); if(heightToSet == 1) return; Message nextMessage = obtainMessage(); bundle.putInt("viewHeight", (heightToSet - 5 > 0) ? heightToSet - 5 : 1); nextMessage.setData(bundle); sendMessage(nextMessage); } 

Agregue esta colección a su adaptador de lista:

 private Collection<Integer> disabledViews = new ArrayList<Integer>(); 

y añada

 public boolean isEnabled(int position) { return !disabledViews.contains(position); } 

A continuación, donde quiera que desee ocultar una fila, añada esto:

 Message message = handler.obtainMessage(); Bundle bundle = new Bundle(); bundle.putInt("viewPosition", listView.getPositionForView(view)); message.setData(bundle); handler.sendMessage(message); disabledViews.add(listView.getPositionForView(view)); 

¡Eso es! Puede cambiar la velocidad de la animación alterando el número de píxeles que reduce la altura a la vez. No es muy sofisticado, pero funciona!

Después de insertar una nueva fila en ListView, sólo desplácese el ListView a la nueva posición.

 ListView.smoothScrollToPosition(position); 

No lo he probado, pero parece que animateLayoutChanges debe hacer lo que está buscando. ¿Lo veo en la clase de ImageSwitcher, asumo que está en la clase de ViewSwitcher también?

Dado que Android es de código abierto, en realidad no es necesario reimplementar las optimizaciones de ListView. Puedes agarrar el código de ListView e intentar encontrar una forma de hackear la animación, también puedes abrir una solicitud de característica en android bug tracker (y si decidiste implementarlo, no olvides contribuir con un parche ).

FYI, el código fuente ListView está aquí .

Este es el código fuente que le permite eliminar filas y reordenarlas.

También hay disponible un archivo APK de demostración. La eliminación de filas se hace más a lo largo de las líneas de la aplicación Gmail de Google que revela una vista inferior después de pasar una vista superior. La vista inferior puede tener un botón Deshacer o lo que quieras.

Como había explicado mi enfoque en mi sitio compartido el link.Anyways la idea es crear mapas de bits por getdrawingcache. Tiene dos mapas de bits y animar el bitmap inferior para crear el efecto de movimiento

Consulte el código siguiente:

 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View rowView, int positon, long id) { listView.setDrawingCacheEnabled(true); //listView.buildDrawingCache(true); bitmap = listView.getDrawingCache(); myBitmap1 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), rowView.getBottom()); myBitmap2 = Bitmap.createBitmap(bitmap, 0, rowView.getBottom(), bitmap.getWidth(), bitmap.getHeight() - myBitmap1.getHeight()); listView.setDrawingCacheEnabled(false); imgView1.setBackgroundDrawable(new BitmapDrawable(getResources(), myBitmap1)); imgView2.setBackgroundDrawable(new BitmapDrawable(getResources(), myBitmap2)); imgView1.setVisibility(View.VISIBLE); imgView2.setVisibility(View.VISIBLE); RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); lp.setMargins(0, rowView.getBottom(), 0, 0); imgView2.setLayoutParams(lp); TranslateAnimation transanim = new TranslateAnimation(0, 0, 0, -rowView.getHeight()); transanim.setDuration(400); transanim.setAnimationListener(new Animation.AnimationListener() { public void onAnimationStart(Animation animation) { } public void onAnimationRepeat(Animation animation) { } public void onAnimationEnd(Animation animation) { imgView1.setVisibility(View.GONE); imgView2.setVisibility(View.GONE); } }); array.remove(positon); adapter.notifyDataSetChanged(); imgView2.startAnimation(transanim); } }); 

Para entender con imágenes vea esto

Gracias.

He hecho algo similar a esto. Una aproximación es interpolar sobre el tiempo de la animación la altura de la visión sobre tiempo dentro de las filas onMeasure mientras que emite requestLayout() para el listView. Sí, puede ser mejor hacer dentro del código listView directamente, pero fue una solución rápida (que se veía bien!)

Sólo compartiendo otro enfoque:

Primero establezca el android de la vista de lista : animateLayoutChanges en true :

 <ListView android:id="@+id/items_list" android:layout_width="match_parent" android:layout_height="match_parent" android:animateLayoutChanges="true"/> 

Luego utilizo un controlador para agregar elementos y actualizar el listview con demora:

 Handler mHandler = new Handler(); //delay in milliseconds private int mInitialDelay = 1000; private final int DELAY_OFFSET = 1000; public void addItem(final Integer item) { mHandler.postDelayed(new Runnable() { @Override public void run() { new Thread(new Runnable() { @Override public void run() { mDataSet.add(item); runOnUiThread(new Runnable() { @Override public void run() { mAdapter.notifyDataSetChanged(); } }); } }).start(); } }, mInitialDelay); mInitialDelay += DELAY_OFFSET; } 
  • Mostrar número de contacto y nombre de contacto en una vista de lista personalizada
  • Optimizar y reducir la sobrecarga de GPU - Android
  • ¿Cómo puedo añadir elementos en una vista de lista para la aplicación de Android?
  • ¿Cómo recuperar más de 1000 filas de Parse.com?
  • Cómo obtener la posición de un elemento de un PopupMenu en un ListView personalizado
  • ¿Cómo puedo cambiar el color de un elemento de vista de lista en Delphi (Firemonkey Android)
  • ¿Cómo hacer que los elementos se puedan hacer clic en la vista de lista?
  • Android lista personalizada con espacio entre los elementos
  • ListView personalizado para AlertDialog
  • El botón de acción flotante no funciona sobre ListView
  • Android: separador personalizado (o incluso elemento) en ListView depening en el contenido del elemento
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.