Cómo animar la eliminación de fragmentos

Quiero animar la eliminación del fragmento.

Lo intenté:

getSupportFragmentManager().beginTransaction() .setCustomAnimations(R.anim.push_down_in, R.anim.push_up_out) .remove(myFragment) .commit(); 

Pero el fragmento simplemente desaparece.

Me di cuenta de que la animación sólo juega con 'reemplazar', así que traté de reemplazar el fragmento con un fragmento vacío como este:

 getSupportFragmentManager() .beginTransaction() .setCustomAnimations(R.anim.push_down_in, R.anim.push_up_out) .replace(viewId, new Fragment()) .commit(); 

Pero todavía desaparece desaparece.

Entonces, ¿cómo puedo animar la eliminación del fragmento?

Me lo imaginé.

La vista de salida se anima en el lienzo de la vista entrante, por lo que si no hay ningún lienzo entrante no hay lienzo para la animación.

Para mostrar la animación que tuve que utilizar siempre reemplazar y utilizar los fragmentos de entrada del mismo tamaño a los que salen. Una vez finalizada la animación, establezco la vista de los nuevos fragmentos.

Vi esto cuando estaba teniendo problemas similares y sólo pensé en dejar una nota rápida.

En lugar de crear un fragmento ficticio con el fin de reemplazar el existente, creo que debería animar la vista de fragmentos actual. Cuando termine la animación, simplemente puede eliminar el fragmento.

Así es como lo hice:

 final FragmentActivity a = getSherlockActivity(); if (a != null) { //Your animation Animation animation = AnimationUtils.loadAnimation(a, R.anim.bottom_out); animation.setDuration(getResources().getInteger(android.R.integer.config_shortAnimTime)); //You can use AnimationListener, MagicAnimationListener is simply a class extending it. animation.setAnimationListener(new MagicAnimationListener() { @Override public void onAnimationEnd(Animation animation) { //This is the key, when the animation is finished, remove the fragment. try { FragmentTransaction ft = a.getSupportFragmentManager().beginTransaction(); ft.remove(RestTimerFragment.this); ft.commitAllowingStateLoss(); } catch (Exception e) { e.printStackTrace(); } } }); //Start the animation. getView().startAnimation(animation); } 

Me inspiró la respuesta de Zoltish, esta es mi implementación:

1.add este método dentro del fragmento, se animará el fragmento de la pantalla a la izquierda:

 public void animateOut() { TranslateAnimation trans=new TranslateAnimation(0,-300*Utils.getDensity(getActivity()), 0,0); trans.setDuration(150); trans.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animation animation) { // TODO Auto-generated method stub ((BetsActivty)getActivity()).removeFrontFragmentAndSetControllToBetting(); } }); getView().startAnimation(trans); } 

El método que dentro onAnimationEnd () elimina el fragmento como este:

 getSupportFragmentManager().beginTransaction(). remove(getSupportFragmentManager().findFragmentById(R.id.fragment_container)).commit(); 

2.Call el animateOut del fragmento de onBack () de la actividad.

Aclamaciones

Por la forma en que mi getDensity () es:

 public static int getDensity(Context context) { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); return (int)metrics.density; } 

Con ello calculo el valor DP para el Dispositivo en funcionamiento.

Razón como @hugoc dijo

La vista de salida se anima en el lienzo de la vista entrante, por lo que si no hay ningún lienzo entrante no hay lienzo para la animación.

Para mostrar la animación que tuve que utilizar siempre reemplazar y utilizar los fragmentos de entrada del mismo tamaño a los que salen. Una vez finalizada la animación, establezco la vista de los nuevos fragmentos.

Abajo está el código real:

 FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.setCustomAnimations(R.anim.slide_in_bottom, R.anim.slide_out_top); transaction.hide(removeFragment).add(R.id.fragment_container,addFragment).commit(); transaction = manager.beginTransaction(); transaction.remove(removeFragment).commit(); 

Reemplazar con un fragmento vacío, antes del punto de inserción del siguiente fragmento y también retrasar la inserción del siguiente fragmento (por 200 ms) para que la animación de salida del fragmento en blanco pueda jugar, resolvió mi problema.

Este es el código para insertar un fragmento vacío con animación de salida.

 getSupportFragmentManager() .beginTransaction() .setCustomAnimations(R.anim.exit, R.anim.pop_exit) .replace(R.id.fragmentLayout, new Fragment()) .commit(); 

Exit.xml

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

Pop_exit.xml

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

Qué entrar:
Es un nuevo fragmento que debe mostrarse

Qué salida:
Es fragmento actual que debe ser ocultar

Qué popEnter:
Es un fragmento anterior que debe mostrarse

Qué popExit:
Es fragmento actual que debe ser ocultar

Para utilizar estas animaciones, debe orientarlas en mostrar u ocultar comandos de transacción. Las animaciones de salida no funcionan en los procedimientos de eliminación / sustitución.

Puede animar la eliminación estableciendo esta animación personalizada en el archivo fragmentTransaction

  fragmentTransaction.setCustomAnimations(R.anim.right_in, R.anim.defff,R.anim.defff,R.anim.right_out); 

El tercero y cuarto params es para el fragmento de extracción

Estoy de acuerdo con hugoc y aquí hay un código para resolverlo

 public class MyActivity extends Activity { //Some thing public void Fragment2BackToFragment1(Fragment fragment1, Fragment fragment2) { FragmentManager manager = getSupportFragmentManager(); FragmentTransaction ft = manager.beginTransaction(); animateExit(fragment2); ft.replace(R.id.main_content, fragment1, "fragment1"); ft.commit(); } private void animateExit(Fragment exitFragment) { if (exitFragment != null) { final View view = exitFragment.getView(); if (view != null) { int anim = R.anim.fade_out; Animation animation = AnimationUtils.loadAnimation(getActivity(), anim); animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { view.postDelayed(new Runnable() { @Override public void run() { view.setVisibility(View.GONE); } }, 300); } @Override public void onAnimationRepeat(Animation animation) { } }); view.startAnimation(animation); } } } } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.