Android ViewPager — плавный переход для этого дизайна

Я не могу понять математику, чтобы сделать плавный переход для следующего дизайна. Любая помощь будет принята с благодарностью :).

Во время перехода страницы прыгают вверх и вниз, но я бы хотел, чтобы они были плавными.

Дизайн

введите здесь описание изображения

Переход

Во время перехода страницы прыгают вверх и вниз, но я бы хотел, чтобы вместо этого они были плавными.

Код Relavent ViewPage:

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


        }
    });

}

Примечание. Для устранения этой ошибки используется 'transformPos' - https://code.google.com/p/android/issues/detail?id=64046

Мой 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"/>

Полный исходный код — https://github.com/krishnaraj/ViewPagerSample


person Krishnaraj    schedule 03.09.2015    source источник
comment
в чем проблема?   -  person Mark Gilchrist    schedule 04.09.2015
comment
@MarkGilchrist Когда вы проводите пальцем влево/вправо, переход не плавный.   -  person Krishnaraj    schedule 04.09.2015
comment
Возможно, вам следует загрузить свой образец проекта на github, чтобы людям было проще проверить, насколько он не гладкий   -  person Derek Fung    schedule 04.09.2015
comment
@DerekFung Добавлена ​​ссылка на репозиторий Github и анимированное изображение.   -  person Krishnaraj    schedule 04.09.2015


Ответы (3)


Попробуй это

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


        }
    });
person Derek Fung    schedule 04.09.2015
comment
Префект работает! ответ blipinsk тоже работает хорошо, но принимает его из-за более короткого кода :) - person Krishnaraj; 04.09.2015

Измените свой if на:

float upTranslation = -pageHeight / 10f;
if (transformPos < -1) {// [-Infinity,-1)
    page.setTranslationY(0);
} else if (transformPos < 0) { // [-1,0)
    float translationY = upTranslation * (transformPos + 1f);
    page.setTranslationY(translationY);
} else if (transformPos == 0) { // 0
    page.setTranslationY(upTranslation);
} else if (transformPos <= 1) { // (0,1]
    float translationY = upTranslation * (1f - transformPos);
    page.setTranslationY(translationY);
} else { // (1,+Infinity]
    page.setTranslationY(0);
}
person Bartek Lipinski    schedule 04.09.2015
comment
Работает хорошо, но не смог найти заметной разницы в финальном переходе между этим и ответом Дерека Фунга. - person Krishnaraj; 04.09.2015
comment
Он работает точно так же (мой код, вероятно, немного более понятен). Честно говоря, я опубликовал ответ, не глядя, появился ли какой-либо другой правильный ответ с тех пор, как я начал писать свой ответ. Но, как я вижу, Дерек Фунг опубликовал свой ответ раньше меня, так что он заслуживает похвалы :). Ваше здоровье! - person Bartek Lipinski; 04.09.2015

Если вам действительно не нужен pageTransformer, используйте код ниже

    viewPager.setPageTransformer(false, new ViewPager.PageTransformer() {
    @Override
    public void transformPage(View page, float position) {
        if(position==1){

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

и попробуй еще раз...

person Rohit Jagtap    schedule 04.09.2015
comment
Но мне нужно поле, чтобы оставить пространство между вкладками. - person Krishnaraj; 04.09.2015
comment
Хорошо, кажется, есть какое-то недоразумение. На самом деле мне нужно, чтобы центральная вкладка была выше, чем вкладки предварительного просмотра (см. обновленное статическое изображение выше). - person Krishnaraj; 04.09.2015
comment
Хорошо, тогда в приведенном выше методе у вас есть позиция, просто поставьте if(position==1){} и переместите внутрь него весь код из этого метода, проверьте обновленный ответ - person Rohit Jagtap; 04.09.2015