Cómo animar la eliminación de fragmentos
Quiero animar la eliminación del fragmento.
Lo intenté:
- Implementar vista como visor de imágenes de facebook - android
- Android Alpha se desvanece en el tema de la animación
- Cómo hacer una rotación de imagen suave en Android?
- Implementar un indicador de actividad giratoria similar a iOS en Android
- Utilizar un ValueAnimator para hacer que un TextView parpadee diferentes colores
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?
- Establecer la página predeterminada de ViewPager en Android
- La vista desaparece cerca del final de la animación RotationY
- Android ViewPropertyAnimator no se escala al mismo tiempo
- Cómo animar vistas como los cambios de desplazamiento de posición de ViewPager
- ¿Cómo encadenar la animación en android a la misma vista?
- Quiero hacer menú de diapositivas con efecto 3D como la imagen de abajo
- Animaciones y setVisibility
- Archivo de animación de estudio de Android
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); } } } }