Skip to content Skip to sidebar Skip to footer

Performing Action After Fragment Transaction Animation Is Finished

I want to set a buttons visibility after the animation is finished. That's what calls the animation: android.support.v4.app.FragmentTransaction fAnimation = this.getActivity().getS

Solution 1:

The Animators that @nmw implements in his answer were added in API Level 11 and will not work with Fragments as implemented by the Android support library.

To listen to Fragment animation events, I extended the support library's Fragment class and overrode onCreateAnimation, attaching a custom AnimationListener to the returned Animation object:

publicclassMyFragmentextendsandroid.support.v4.app.Fragment {

    privatestaticfinalStringTAG="MyFragment";

    @Overridepublic Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {

        Animationanim= AnimationUtils.loadAnimation(getActivity(), nextAnim);

        anim.setAnimationListener(newAnimationListener() {

            @OverridepublicvoidonAnimationStart(Animation animation) {
                Log.d(TAG, "Animation started.");
                // additional functionality 
            }

            @OverridepublicvoidonAnimationRepeat(Animation animation) {
                Log.d(TAG, "Animation repeating.");
                // additional functionality
            }

            @OverridepublicvoidonAnimationEnd(Animation animation) {
                Log.d(TAG, "Animation ended.");
                // additional functionality
            }
        });

        return anim;
    }
}

Solution 2:

You need to subclass Fragment and override onCreateAnimator, then you can load those animations from XML and attach listeners to them.

E.g.

publicclassMyFragmentextendsFragment
{
    @Overridepublic Animator onCreateAnimator(int transit, boolean enter, int nextAnim)
    {
        finalintanimatorId= (enter) ? R.anim.in_anim : R.anim.out_anim;
        finalAnimatoranim= AnimatorInflater.loadAnimator(getActivity(), animatorId);
        anim.addListener(newAnimatorListenerAdapter()
        {
            @OverridepublicvoidonAnimationStart(Animator animation)
            {
                ...
            }

            @OverridepublicvoidonAnimationEnd(Animator animation)
            {
               ...
            }
        });

        return anim;
   }    

Solution 3:

Combining the answers above here is a sample I am using successfully with the support library fragments.

Simply extend the MenuFragment and set the listener to get a callback of what to execute afterwards.

publicclassMenuFragmentextendsFragment {

private WeakReference<OnMenuClosedListener> onMenuClosedListener;

@Overridepublic Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    Animationanim=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(newAnimationListener() {
            @OverridepublicvoidonAnimationStart(Animation animation) {
            }
            @OverridepublicvoidonAnimationRepeat(Animation animation) {
            }
            @OverridepublicvoidonAnimationEnd(Animation animation) {
                onMenuClosed();
            }
        });
    }

    // NOTE: the animation must be added to an animation set in order for the listener// to work on the exit animationAnimationSetanimSet=newAnimationSet(true);
    animSet.addAnimation(anim);

    return animSet;
}

privatevoidonMenuClosed() {
    if (this.onMenuClosedListener != null) {
        OnMenuClosedListenerlistener=this.onMenuClosedListener.get();
        if (listener != null) {
            listener.onMenuClosed();
        }
    }
}

publicvoidsetOnMenuClosedListener(OnMenuClosedListener listener) {
    this.onMenuClosedListener = newWeakReference<MenuFragment.OnMenuClosedListener>(listener);
}

/**
 * Callback for when the menu is closed.
 */publicstaticinterfaceOnMenuClosedListener {

    publicabstractvoidonMenuClosed();

}

}

Solution 4:

Added in API 26 (and in Support Library) you can use

FragmentTransaction runOnCommit(Runnable runnable);

For example:

FragmentTransactionft= getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_from_left);
ft.show(YourFragment);
ft.commit();
ft.runOnCommit(() -> Your_Action_Here);

Solution 5:

I had to do this in Xamarin. My situation was I needed a callback once the fragment animation ended. Here is how I made it work without any flickering (this is C#/Xamarin):

publicoverride 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;
    }

    publicvoidOnAnimationEnd(Animation animation)
    {
    }

    publicvoidOnAnimationRepeat(Animation animation)
    {
    }

    publicvoidOnAnimationStart(Animation animation)
    {
    }

Note:

  • The parent fragment has to implement Animation.IAnimationListener
  • You have to return an AnimationSet otherwise the FragmentManager will override your listener and the callbacks won't fire.

Post a Comment for "Performing Action After Fragment Transaction Animation Is Finished"