FragmentTransaction animation to slide in over top
Update (June 16, 2020)
Starting from fragment library 1.2.0
the recommanded way to fix this issue is to use FragmentContainerView
with FragmentTransaction.setCustomAnimations()
.
According to the documentation:
Fragments using exit animations are drawn before all others for FragmentContainerView. This ensures that exiting Fragments do not appear on top of the view.
Steps to fix this issue are:
- Update fragment library to 1.2.0 or more
androidx.fragment:fragment:1.2.0
; - Replace your xml fragment container (
<fragment>
,<FrameLayout>
, or else) by<androidx.fragment.app.FragmentContainerView>
; - Use
FragmentTransaction.setCustomAnimations()
to animate your fragments transitions.
Previous answer (Nov 19, 2015)
Starting from Lollipop, you can increase de translationZ of your entering fragment. It will appear above the exiting one.
For example:
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewCompat.setTranslationZ(getView(), 100.f);
}
If you want to modify the translationZ value only for the duration of the animation, you should do something like this:
@Override
public Animation onCreateAnimation(int transit, final boolean enter, int nextAnim) {
Animation nextAnimation = AnimationUtils.loadAnimation(getContext(), nextAnim);
nextAnimation.setAnimationListener(new Animation.AnimationListener() {
private float mOldTranslationZ;
@Override
public void onAnimationStart(Animation animation) {
if (getView() != null && enter) {
mOldTranslationZ = ViewCompat.getTranslationZ(getView());
ViewCompat.setTranslationZ(getView(), 100.f);
}
}
@Override
public void onAnimationEnd(Animation animation) {
if (getView() != null && enter) {
ViewCompat.setTranslationZ(getView(), mOldTranslationZ);
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
return nextAnimation;
}
I don't know if you still need an answer but I recently needed to do the same and I found a way to do what you want.
I made something like this :
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
MyFragment next = getMyFragment();
ft.add(R.id.MyLayout,next);
ft.setCustomAnimations(R.anim.slide_in_right,0);
ft.show(next);
ft.commit();
I display my Fragment in a FrameLayout.
It work fines but the older Fragment is still in my View, I let android manage it like he wants because if I put:
ft.remove(myolderFrag);
it is not displayed during the animation.
slide_in_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate android:duration="150" android:fromXDelta="100%p"
android:interpolator="@android:anim/linear_interpolator"
android:toXDelta="0" />
</set>