overridependingtransition fragments example entre animations animaciones android android-fragments android-animation

android - fragments - overridependingtransition fragment



Realizar la acción después de que la animación de transacción de fragmento haya finalizado (4)

Quiero establecer la visibilidad de los botones una vez finalizada la animación.

Eso es lo que llama la animación:

android.support.v4.app.FragmentTransaction fAnimation = this.getActivity().getSupportFragmentManager().beginTransaction(); fAnimation.setCustomAnimations(android.R.anim.slide_in_left, R.anim.pull_out_to_left); if (this.isVisible()) { fAnimation.hide(this); fAnimation.commit(); } // code that will be executed when the fragment is gone (after the animation is over)

¿Hay alguna manera de conectar un oyente para saber cuándo se ha ido mi fragmento?


La combinación de las respuestas anteriores aquí es una muestra que estoy utilizando con éxito con los fragmentos de la biblioteca de soporte.

Simplemente extienda MenuFragment y configure el oyente para obtener una devolución de llamada de lo que se ejecutará después.

public class MenuFragment extends Fragment { private WeakReference<OnMenuClosedListener> onMenuClosedListener; @Override public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { Animation anim = null; if (enter) { anim = AnimationUtils.loadAnimation(getActivity(), R.anim.anim_slide_in_top); } else { anim = AnimationUtils.loadAnimation(getActivity(), R.anim.anim_menu_slide_out_top); anim.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { onMenuClosed(); } }); } // NOTE: the animation must be added to an animation set in order for the listener // to work on the exit animation AnimationSet animSet = new AnimationSet(true); animSet.addAnimation(anim); return animSet; } private void onMenuClosed() { if (this.onMenuClosedListener != null) { OnMenuClosedListener listener = this.onMenuClosedListener.get(); if (listener != null) { listener.onMenuClosed(); } } } public void setOnMenuClosedListener(OnMenuClosedListener listener) { this.onMenuClosedListener = new WeakReference<MenuFragment.OnMenuClosedListener>(listener); } /** * Callback for when the menu is closed. */ public static interface OnMenuClosedListener { public abstract void onMenuClosed(); }

}


Los Animadores que @nmw implementa en su respuesta se agregaron en API Nivel 11 y no funcionarán con los Fragmentos implementados por la biblioteca de soporte de Android.

Para escuchar los eventos de animación Fragment, extendí la clase Fragment la biblioteca de soporte y onCreateAnimation , adjuntando un AnimationListener personalizado al objeto de animación devuelto:

public class MyFragment extends android.support.v4.app.Fragment { private static final String TAG = "MyFragment"; @Override public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { Animation anim = AnimationUtils.loadAnimation(getActivity(), nextAnim); anim.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { Log.d(TAG, "Animation started."); // additional functionality } @Override public void onAnimationRepeat(Animation animation) { Log.d(TAG, "Animation repeating."); // additional functionality } @Override public void onAnimationEnd(Animation animation) { Log.d(TAG, "Animation ended."); // additional functionality } }); return anim; } }


Necesita subclase Fragment y anular onCreateAnimator, luego puede cargar esas animaciones desde XML y adjuntar oyentes a ellas.

P.ej

public class MyFragment extends Fragment { @Override public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) { final int animatorId = (enter) ? R.anim.in_anim : R.anim.out_anim; final Animator anim = AnimatorInflater.loadAnimator(getActivity(), animatorId); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { ... } @Override public void onAnimationEnd(Animator animation) { ... } }); return anim; }


Tenía que hacer esto en Xamarin. Mi situación era que necesitaba una devolución de llamada una vez que terminó la animación del fragmento. Aquí es cómo lo hice funcionar sin ningún parpadeo (esto es C # / Xamarin):

public override Animation OnCreateAnimation(int transit, bool enter, int nextAnim) { Animation anim = base.OnCreateAnimation(transit, enter, nextAnim); if (anim == null && nextAnim != 0) { anim = AnimationUtils.LoadAnimation(Activity, nextAnim); } anim.SetAnimationListener(this); return anim; } public void OnAnimationEnd(Animation animation) { } public void OnAnimationRepeat(Animation animation) { } public void OnAnimationStart(Animation animation) { }

Nota:

  • El fragmento principal tiene que implementar Animation.IAnimationListener
  • Tienes que devolver un AnimationSet contrario, FragmentManager anulará tu oyente y las devoluciones de llamada no se activarán.