web-dev-qa-db-fra.com

Exécution d'une action une fois l'animation de transaction de fragment terminée

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?

53
Moop

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;
    }
}
62
mjama

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;
   }    
16
nmw

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();

}

}

7
Meanman

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);
4
Giuseppe Sarno

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:

  • Le fragment parent doit implémenter Animation.IAnimationListener
  • Vous devez renvoyer un AnimationSet sinon le FragmentManager remplacera votre écouteur et les rappels ne se déclencheront pas.
0
pnavk