studio ejemplo custom changes animations animate android android-layout android-listview android-animation

ejemplo - custom listview android studio



Anima la eliminaciĆ³n de un elemento ListView (4)

Estoy intentando animar la eliminación de un elemento ListView usando esto:

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, final View view, final int i, long l) { view.animate().setDuration(500).x(-view.getWidth()).alpha(0f); adapter.remove(tasks.get(i)); adapter.notifyDataSetChanged(); } });

No funciona. Básicamente, seguí el consejo de la cuarta respuesta desde la parte superior de esta publicación:

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

Sin embargo, hay algunas cosas graciosas de dibujo en curso, o reciclaje, o algo así porque, mientras se produce la animación, el elemento debajo del que se desliza fuera de la pantalla también se elimina por alguna razón. La respuesta que la pregunta asker finalmente marcó como correcta es desafortunadamente un RTFM hacia toda la fuente de Android. Miré por allí y no puedo encontrar las notificaciones desplegables en JellyBean que estoy tratando de emular.

TIA. John


Acabo de encontrar una hermosa solución: https://github.com/paraches/ListViewCellDeleteAnimation

Aquí hay un video: http://www.youtube.com/watch?v=bOl5MIti7n0

Muchas gracias a ''paraches'';)

Editar

A partir de la versión de Android 22.0.0, el nuevo android.support.v7.widget.RecyclerView está disponible como un sucesor de ListView . Las animaciones estándar de agregar / quitar / actualizar están disponibles de manera inmediata. Las animaciones de widget también son fáciles de personalizar ( pocas animaciones personalizadas ).

Recomiendo cambiar de ListView a RecyclerView si necesita animaciones de elementos personalizados.


Como señala Chet Haase en DevBytes, https://www.youtube.com/watch?v=8MIfSxgsHIs , todo esto funcionará, pero no olvides agregar flags de transientState.

De su código:

// Here''s where the problem starts - this animation will animate a View object. // But that View may get recycled if it is animated out of the container, // and the animation will continue to fade a view that now contains unrelated // content. ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.ALPHA, 0); anim.setDuration(1000); if (setTransientStateCB.isChecked()) { // Here''s the correct way to do this: if you tell a view that it has // transientState, then ListView ill avoid recycling it until the // transientState flag is reset. // A different approach is to use ViewPropertyAnimator, which sets the // transientState flag internally. view.setHasTransientState(true); } anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { cheeseList.remove(item); adapter.notifyDataSetChanged(); view.setAlpha(1); if (setTransientStateCB.isChecked()) { view.setHasTransientState(false); } } }); anim.start();


He utilizado la animación de diapositivas de arriba a abajo al actualizar ListView. Aquí está el código que utilicé:

adapter.notifyDataSetChanged(); Animation animation = AnimationUtils.loadAnimation( getApplication(), R.anim.slide_top_to_bottom); getListView().startAnimation(animation); getListView().setSelection(0);

y slide_top_to_bottom.xml (guárdelo dentro de la carpeta res/anim )

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> <translate android:fromYDelta="-100%" android:toXDelta="0" android:duration="100" /> <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="50" /> </set>

EDITAR: Prueba esto:

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, final View view, final int i, long l) { ValueAnimator fader = ObjectAnimator.ofFloat(view, "alpha", 1, 0); AnimatorSet animation = new AnimatorSet(); animation.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } }); ((AnimatorSet) animation).play(fader); animation.setDuration(500); animation.start(); adapter.remove(tasks.get(i)); adapter.notifyDataSetChanged(); } });


Idea: inicio la animación cuando el usuario selecciona la fila. Cuando la animación se completa, elimino la fila del adaptador. El siguiente código anima la fila seleccionada:

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final ListView listView = (ListView) findViewById(R.id.listView1); final ArrayList<String> values = new ArrayList<String>(); values.add("Android"); values.add("iPhone"); values.add("WindowsMobile"); values.add("Blackberry"); values.add("Windows7"); final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, values); listView.setAdapter(adapter); final Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_out); animation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { adapter.remove(adapter.getItem(selectedRow)); adapter.notifyDataSetChanged(); } }); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(getApplicationContext(), " " + values.get(position), Toast.LENGTH_LONG).show(); view.startAnimation(animation); selectedRow = position; } }); }

archivo slide_out.xml:

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:fromYDelta="0%" android:toYDelta="100%" android:duration="@android:integer/config_mediumAnimTime"/> </set>