Performing Action After Fragment Transaction Animation Is Finished
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 theFragmentManager
will override your listener and the callbacks won't fire.
Post a Comment for "Performing Action After Fragment Transaction Animation Is Finished"