androidandroid-viewpagerandroid-pagetransformer

Android ViewPager - Smooth Transition for this Design


I can't really figure out the math to do smooth transition for the following design. Any help would be greatly appreciated :).

During transition, the pages are jumping up and down but I would like them to be smooth instead.

Design

enter image description here

Transition

During transition, the pages are jumping up and down but I would like them to be smooth instead.

Relavent ViewPage code:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
    PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(pagerAdapter);
    viewPager.setOffscreenPageLimit(3);
    viewPager.setPageMargin(100);
    viewPager.setPageTransformer(false, new ViewPager.PageTransformer() {
        @Override
        public void transformPage(View page, float position) {
            int pageWidth = viewPager.getMeasuredWidth() - viewPager.getPaddingLeft() - viewPager.getPaddingRight();
            int pageHeight = viewPager.getHeight();
            int paddingLeft = viewPager.getPaddingLeft();
            float transformPos = (float) (page.getLeft() - (viewPager.getScrollX() + paddingLeft)) / pageWidth;

            final float normalizedposition = Math.abs(Math.abs(transformPos) - 1);
            page.setAlpha(normalizedposition + 0.5f);

            if (transformPos < -1) { // [-Infinity,-1)
                // This page is way off-screen to the left.
                page.setTranslationY(0);
            } else if (transformPos <= 1) { // [-1,1]
                page.setTranslationY(-pageHeight / 10);

            } else { // (1,+Infinity]
                // This page is way off-screen to the right.
                page.setTranslationY(0);
            }


        }
    });

}

Note: 'transformPos' is used to address this bug - https://code.google.com/p/android/issues/detail?id=64046

My ViewPager

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="260dp"
    android:layout_centerInParent="true"
    android:clipToPadding="false"
    android:paddingLeft="80dp"
    android:paddingRight="80dp"/>

Full Source - https://github.com/krishnaraj/ViewPagerSample


Solution

  • Try this

        viewPager.setPageTransformer(false, new ViewPager.PageTransformer() {
            @Override
            public void transformPage(View page, float position) {
                int pageWidth = viewPager.getMeasuredWidth() - viewPager.getPaddingLeft() - viewPager.getPaddingRight();
                int pageHeight = viewPager.getHeight();
                int paddingLeft = viewPager.getPaddingLeft();
                float transformPos = (float) (page.getLeft() - (viewPager.getScrollX() + paddingLeft)) / pageWidth;
    
                final float normalizedposition = Math.abs(Math.abs(transformPos) - 1);
                page.setAlpha(normalizedposition + 0.5f);
    
                int max = -pageHeight / 10;
    
                if (transformPos < -1) { // [-Infinity,-1)
                    // This page is way off-screen to the left.
                    page.setTranslationY(0);
                } else if (transformPos <= 1) { // [-1,1]
                    page.setTranslationY(max * (1-Math.abs(transformPos)));
    
                } else { // (1,+Infinity]
                    // This page is way off-screen to the right.
                    page.setTranslationY(0);
                }
    
    
            }
        });