Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit Z-Ordering For ViewPagers

I am trying to implement a ViewPager.PageTransformer that is nearly identical to the example found here labeled DepthPageTransformer (it is at the bottom of the page).

However, instead of having the hierarchy follow a pattern where z-index decreases from left to right (i.e. views to the right will appear from below), I would like the z-index to increase from left to right (views to the left will appear from below).

As a first attempt, i basically swapped the code in the example that represented pages coming in from the left vs. the right, but I found that there was an implicit z-ordering such that pages on the left were always above pages to the right, so as you swipe to see a page to the right, it will slide in fine but the view that disappears will disappear "on top" of the newly entered view.

Is there any way to adjust the z-indices of the pages served by a ViewPager?

My first instinct is to somehow copy the ViewPager code from the support library, and modify the class to do my bidding, but it isn't clear to me where in that class the implicit ordering comes about.

Here is my (majorly ripped off) 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);
        }
    }
}
like image 604
Daniel Smith Avatar asked Mar 19 '13 21:03

Daniel Smith


1 Answers

The drawing order of the ViewPager pages is determined by the first parameter of the ViewPager.setPageTransformer() method.

See the method signature:

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

The reverseDrawingOrder parameter documentation says: "true if the supplied PageTransformer requires page views to be drawn from last to first instead of first to last."

Internally, when the ViewPager page drawing order is being determined, it calls:

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

The mDrawingOrder is set internally by the reverseDrawingOrder boolean flag in ViewPager.setPageTransformer()

like image 159
Jay Ohms Avatar answered Nov 08 '22 11:11

Jay Ohms