ViewPager的隐式Z轴排序

5

我正在尝试实现一个几乎与此处标记为DepthPageTransformer的示例完全相同的ViewPager.PageTransformer(它位于页面底部)。

然而,与其让层次结构遵循从左到右递减的模式(即,向右的视图将从下面出现),我想让z-index从左到右递增(向左的视图将从下面出现)。

作为第一次尝试,我基本上交换了示例中代表从左侧和右侧进入页面的代码,但我发现存在一种隐式的z-ordering,使得左侧的页面总是在右侧页面之上,因此当您滑动以查看右侧的页面时,它会正常滑入,但消失的视图将“顶部”消失在新输入的视图上。

是否有任何方法可以调整由ViewPager提供的页面的z-index?

我的第一反应是以某种方式复制支持库中的ViewPager代码,并修改该类以执行我的命令,但我不清楚在哪个类中隐含的排序发生。

这是我(主要是抄袭的)PageTransformer

public class DepthPageTransformer implements ViewPager.PageTransformer {
    private static float MIN_SCALE = 0.75f;

    public void transformPage(View view, float position) {

        int pageWidth = view.getWidth();

        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.setAlpha(0);

        } else if (position <= 0) { // [-1,0]  
            view.setAlpha(1 + position);

            // Counteract the default slide transition
            view.setTranslationX(pageWidth * -position);

            // Scale the page down (between MIN_SCALE and 1)
            float scaleFactor = MIN_SCALE
                    + (1 - MIN_SCALE) * (1 - Math.abs(position));
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);

        } else if (position <= 1) { // (0,1]            
            view.setAlpha(1);
            view.setTranslationX(0);
            view.setScaleX(1);
            view.setScaleY(1);

        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.setAlpha(0);
        }
    }
}
2个回答

13

ViewPager页面的绘制顺序由ViewPager.setPageTransformer()方法的第一个参数决定。

请参见该方法的签名:

public void setPageTransformer (boolean reverseDrawingOrder, ViewPager.PageTransformer transformer)

reverseDrawingOrder参数的文档说明:如果提供的PageTransformer需要将页面视图从后往前绘制而不是从前往后,则为true

在内部确定ViewPager页面绘制顺序时,它调用:

protected int getChildDrawingOrder(int childCount, int i) {
    final int index = mDrawingOrder == DRAW_ORDER_REVERSE ? childCount - 1 - i : i;
    final int result = ((LayoutParams) mDrawingOrderedChildren.get(index).getLayoutParams()).childIndex;
    return result;
}

ViewPager.setPageTransformer()中的reverseDrawingOrder布尔标记会在内部设置mDrawingOrder


在ViewPager代码的最底部还有一个名为ViewPositionComparator的类,它用于实际确定页面的排序。你的答案让我找到了它。 - Daniel Smith
这个答案非常好。如果你将 ViewPager.setPageTransformer() 的第一个参数改为 false,那么在你的类中只需将 view.setTranslationX(pageWidth * -position); 改为 view.setTranslationX(0);,反之亦然。就这样,你不必去访问 ViewPager 类中的任何其他方法。 - AlexAndro
天啊,我都快被这个问题搞疯了..不得不感谢你! - Mateus Brandao
对于那些在页面转换中看到随机页面排序的人,这里有一个提示:如果你正在进行自制回收并重复使用页面视图,则回收的LayoutParams会使ViewPager混淆Z顺序,因为位置顺序被保留在那里。在重新添加到ViewPager之前,请确保将LayoutParams重置为一些合理的通用ViewGroup.LayoutParams值。 - kris larson

0

你可以使用 .bringToFront(); 方法。


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