I have below code for setting enter and exit animations for fragments.
final FragmentManager manager = getSupportFragmentManager();
final FragmentTransaction ft = manager.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right);
ft.replace(R.id.container, fragment, tag);
ft.addToBackStack(tag);
ft.commitAllowingStateLoss();
slide_in_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%"
android:toXDelta="0%"
android:duration="@integer/slide_anim_duration" />
</set>
Used same method for all other animations. Works fine in all other versions, but the problem is in Lollipop only. As we look in to the function setCustomAnimations (int enter, int exit, int popEnter, int popExit)
doc-link , enter
and exit
works fine, but popEnter
and popExit
fails in Lollipop.
Please guide me about what went wrong and provide a compatible solution that works from Android 2.3 to 5.1
Update:
Observing closely,it seems that the animation is there, but the duration has no effect.
Fragment animations are broken even before L - there are some issues when changing screen orientation.
Below solution fixes both L issues and earlier orientation change issues. Use it as your base Fragment class.
public abstract class AnimatedSupportFragment extends DaggerFragment {
private static final String STATE_ENTER_ANIM = "STATE_ENTER_ANIM";
private static final String STATE_EXIT_ANIM = "STATE_EXIT_ANIM";
private static final String STATE_POP_ENTER_ANIM = "STATE_POP_ENTER_ANIM";
private static final String STATE_POP_EXIT_ANIM = "STATE_POP_EXIT_ANIM";
private static final String STATE_CHANGING_CONFIGURATIONS = "STATE_CHANGING_CONFIGURATIONS";
private @AnimRes int mEnter = 0;
private @AnimRes int mExit = 0;
private @AnimRes int mPopEnter = 0;
private @AnimRes int mPopExit = 0;
private boolean mIsChangingConfigurations = false;
public void setCustomAnimations(@AnimRes int enterAnim,
@AnimRes int exitAnim,
@AnimRes int popEnterAnim,
@AnimRes int popExitAnim) {
mEnter = enterAnim;
mExit = exitAnim;
mPopEnter = popEnterAnim;
mPopExit = popExitAnim;
}
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mEnter = savedInstanceState.getInt(STATE_ENTER_ANIM);
mExit = savedInstanceState.getInt(STATE_EXIT_ANIM);
mPopEnter = savedInstanceState.getInt(STATE_POP_ENTER_ANIM);
mPopExit = savedInstanceState.getInt(STATE_POP_EXIT_ANIM);
mIsChangingConfigurations = savedInstanceState.getBoolean(STATE_CHANGING_CONFIGURATIONS);
}
}
@Override public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_ENTER_ANIM, mEnter);
outState.putInt(STATE_EXIT_ANIM, mExit);
outState.putInt(STATE_POP_ENTER_ANIM, mPopEnter);
outState.putInt(STATE_POP_EXIT_ANIM, mPopExit);
outState.putBoolean(STATE_CHANGING_CONFIGURATIONS, mIsChangingConfigurations);
}
@Override public void onResume() {
super.onResume();
mIsChangingConfigurations = false;
}
@Override public void onPause() {
super.onPause();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mIsChangingConfigurations = getActivity().isChangingConfigurations();
}
}
@SuppressLint("NewApi")
@Override public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
// This implementation fixes loosing transition animations on orientation changes:
// @see http://stackoverflow.com/questions/8837408/fragment-lost-transition-animation-after-configuration-change
// @see https://code.google.com/p/android/issues/detail?id=25994&can=4&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
// Do not support animations PRE-3.0, isChangingConfigurations() is not available!
return null;
}
try {
int anim;
if (mIsChangingConfigurations) {
// Recreating after change configuration, we don't want to play animation
anim = 0;
} else if (nextAnim != 0) {
// Animation available (not lost) -> play it!
anim = nextAnim;
} else {
// Animation probably lost - load anim saved in fragment state.
// enter = we're about to play popEnterAnim, in other case popExitAnimation
anim = enter ? mPopEnter : mPopExit;
}
if (anim != 0) {
return AnimationUtils.loadAnimation(getActivity(), anim);
}
} catch (Exception ignore) {}
return null;
}
}
you can additionally try onCreateAnimator in all the fragments..or the base fragment that they are extending...
@target_api 20 or higher
@Override
public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
if (enter) {
return AnimatorInflater.loadAnimator(getActivity(), R.animator.slide_in_top);
} else {
return AnimatorInflater.loadAnimator(getActivity(), R.animator.fade_out);
}
}
Note both above animators are pre defined and R there is android.R
Hope this helps cheers!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With