在进行FragmentTransaction期间更改Fragment的z-order

11

有没有方法可以在 ongoing FragmentTransaction 中更改碎片显示的 z-order? 我有一个动画,其中两个碎片彼此重叠,我希望从右侧滑动的碎片(第二个碎片)显示在从左侧滑动的另一个碎片下方。目前它们在交易期间以相反的顺序显示。

这是我其中一种动画的代码:

<?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>

这里是交易的代码

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.show(fragmentToShow).hide(fragmentToHide).commit();

我希望fragmentToHidefragmentToShow下方出现。 我尝试使用android:zAdjustment属性解决问题,但由于它似乎只适用于窗口动画,所以对我没有用。


1
我遇到了类似的问题。你找到了一种改变z-order的方法,使得在.replace()过渡期间出现的片段位于顶部吗? - Moritz
2个回答

3
我也遇到了这个问题,唯一的解决方法是在当前的Fragment布局下方添加一个新的FrameLayout。然后,我将新的Fragment转换到新的FrameLayout中(该FrameLayout比下面的FrameLayout有更高的Z顺序),并在同一操作中从原始FrameLayout中删除旧的Fragment。示例代码如下:
<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>

是的,我知道这会向层次结构中添加一个额外的视图,但它不会增加树的深度。为了进一步提高性能,我在我的片段中覆盖了onCreateAnimator函数,以将动画卸载到硬件层中,如下所示:

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

这是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);
    }
}

分层在两个不同的框架中对我起作用了,但是这是一个相当丑陋的解决方案,尽管目前是我所知道的最好的片段解决方案。 - arberg

3
使用ViewCompat.setTranslationZ(),在您的新片段中添加以下内容。
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    ViewCompat.setTranslationZ(getView(), 1f);
}

默认的 trasnlationZ 值为0。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接