Je souhaite définir la visibilité des boutons une fois l'animation terminée.
C'est ce qui appelle l'animation:
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)
Existe-t-il un moyen d'attacher un auditeur pour savoir quand mon fragment a disparu?
Les animateurs que @nmw implémente dans sa réponse ont été ajoutés dans l'API niveau 11 et ne fonctionneront pas avec les fragments mis en œuvre par la bibliothèque de support Android Android.
Pour écouter les événements d'animation Fragment, j'ai étendu la classe Fragment
de la bibliothèque de support et remplacé onCreateAnimation
, en attachant un AnimationListener personnalisé à l'objet Animation renvoyé:
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;
}
}
Vous devez sous-classer Fragment et remplacer onCreateAnimator, puis vous pouvez charger ces animations à partir de XML et y attacher des écouteurs.
Par exemple.
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;
}
La combinaison des réponses ci-dessus est un exemple que j'utilise avec succès avec les fragments de la bibliothèque de support.
Étendez simplement le MenuFragment et définissez l'auditeur pour obtenir un rappel de ce qu'il faut exécuter ensuite.
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();
}
}
Ajouté dans l'API 26 (et dans la bibliothèque de support), vous pouvez utiliser
FragmentTransaction runOnCommit (Runnable runnable);
Par exemple:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_from_left);
ft.show(YourFragment);
ft.commit();
ft.runOnCommit(() -> Your_Action_Here);
Je devais le faire à Xamarin. Ma situation était que j'avais besoin d'un rappel une fois l'animation du fragment terminée. Voici comment je l'ai fait fonctionner sans scintillement (c'est 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)
{
}
Remarque:
Animation.IAnimationListener
AnimationSet
sinon le FragmentManager
remplacera votre écouteur et les rappels ne se déclencheront pas.