marco marco - 1 month ago 17
Android Question

ViewPager.PageTransformer with a drop shadow

I have a stack of fragments in a ViewPager, with a custom PageTransformer defined as below.

mPager.setPageTransformer(true, new ViewPager.PageTransformer() {
@Override
public void transformPage(View page, float position) {
page.setTranslationX(page.getWidth() * -position);
}
});


How can I draw a shadow for the leaving fragment ?
Long story short I'm looking for something as in Play Book, no curl effects needed, just the shadow of the element on the top of the stack, preferably API 18 compliant

Thank you

Answer

I had doubts about setPageMargin because it works only if the incoming view has an alpha transparency. I mean, it seems that the margin has a wrong elevation and it stands below the incoming view, but maybe I've found a compromise

enter image description here

This is the code in the activity for the margin and the custom PageTransformer

    int margin = getResources().getDisplayMetrics().widthPixels / 15;
    mPager = (ViewPager) findViewById(R.id.pager);

    mPager.setPageMargin(margin);
    mPager.setPageMarginDrawable(R.drawable.shadow);
    mPager.setPageTransformer(true, new StackTransformer());

where the drawable is defined as

    <shape xmlns:android="http://schemas.android.com/apk/res/android" 
       android:shape="rectangle" >
        <gradient
            android:angle="360"
            android:endColor="#00000000"
            android:startColor="#aa000000"
            android:type="linear" />
    </shape>

At last the transformPage method of the PageTransformer, where I played with position and alpha to find an acceptable effect

@Override
public void transformPage(View view, float position) {
    int pageWidth = view.getWidth();
    if (position < -1) {
        view.setAlpha(0);
    } else if (position <= 0) { 
        view.setAlpha(1);
        view.setTranslationX(0);
    } else if (position <= 1) { 
        view.setAlpha(1-position/2); // divide by 2 is the trick
        view.setTranslationX(pageWidth * -position);
    } else { 
        view.setAlpha(0);
    }
}

The resulting effect is what you see in the gif above, but I'm sure that out there, there is a better way to achieve this effect

Comments