Is there a way how to change the z-order in which are fragments displayed during an ongoing FragmentTransaction? I've an animation where both fragments overlaps each other and I would like to have the fragment which slides from the right (the second fragment) displayed under the other one which slides to the left. Right now they are displayed in opposite order during the transaction.
Here is code of one of my animations:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="400"
android:zAdjustment="bottom">
<scale android:toXScale="1"
android:fromXScale="0.9"
android:pivotX="50%p"
android:pivotY="50%p"
android:toYScale="1"
android:startOffset="300"
android:fromYScale="0.9"/>
<translate android:fromXDelta="50%p"
android:interpolator="@android:interpolator/overshoot"
android:toXDelta="0"/>
</set>
And here is the code of the transaction
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.show(fragmentToShow).hide(fragmentToHide).commit();
I would like to have the fragmentToHide
to appear under the fragmentToShow
.
I've tried to tackle with the android:zAdjustment
property, but since it apparently works only for window animations it just haven't worked for me.
Step 1 − Create a new project in Android Studio, go to File ⇉ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml. Step 3 − Create two FragmentActivity and add the codes which are given below.
At a high level, here's how to make a fragment transition with shared elements: Assign a unique transition name to each shared element view. Add shared element views and transition names to the FragmentTransaction . Set a shared element transition animation.
The android:name attribute specifies the class name of the Fragment to instantiate. When the activity's layout is inflated, the specified fragment is instantiated, onInflate() is called on the newly instantiated fragment, and a FragmentTransaction is created to add the fragment to the FragmentManager .
I also had this problem and the only workaround I have been able to find is to place another FrameLayout directly under the one that holds the current fragment. Then I transition my new fragment into the alternate FrameLayout (which has a higher z-ordering than the FrameLayout below it) and remove the old fragment from the original FrameLayout in the same transaction. Something like this:
<FrameLayout
android:id="@+id/video_list_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<FrameLayout
android:id="@+id/video_player_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
Yes, I know this adds an additional view to the hierarchy but it doesn't increase the tree depth. For additional performance boost I override onCreateAnimator in my fragments to offload the animation to the hardware layer, like so:
@Override
public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
Animator animation = super.onCreateAnimator(transit, enter, nextAnim);
// HW layer support only exists on API 11+
if (Build.VERSION.SDK_INT >= 11) {
if (animation == null && nextAnim != 0) {
animation = AnimatorInflater.loadAnimator(getActivity(), nextAnim);
}
if (animation != null) {
animation.addListener(new LayerEnablingAnimatorListener(getView()));
}
}
return animation;
}
And this is LayerEnablingAnimatorListener:
public class LayerEnablingAnimatorListener extends AnimatorListenerAdapter {
private final View mTargetView;
private int mLayerType;
public LayerEnablingAnimatorListener(View targetView) {
mTargetView = Objects.requireNonNull(targetView, "Target view cannot be null");
}
public View getTargetView() {
return mTargetView;
}
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
mLayerType = mTargetView.getLayerType();
mTargetView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mTargetView.setLayerType(mLayerType, null);
}
}
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