Android viewpager синхронизированная прокрутка - PullRequest
1 голос
/ 05 октября 2011

У меня есть два ViewPager - Pager1 и Pager2. Я добавил OnPageChangeListener в Pager1 и в обратном вызове onPageScrolled я вызываю Pager2.scrollTo (x, y), чтобы переместить его. Оба ViewPager выполняют плавную прокрутку и синхронизируются, но проблема в том, что содержимое Pager2 не изменяется. Я проверил это с помощью LogCat - instantiateItem () для Pager2 вообще не вызывается.

В качестве обходного пути я добавил Pager2.setCurrentItem () к обратному вызову onPageSelected () для Pager1. Хотя это прокручивает оба просмотра, оно не синхронизируется с пикселем. Мне интересно, есть ли способ достичь этого эффекта без необходимости переопределять реальный класс ViewPager.

Ответы [ 2 ]

0 голосов
/ 27 апреля 2017

Лучшим решением для меня было передать MotionEvent в OnTouchListener между ViewPager экземплярами. Пробовал фальшивое перетаскивание, но оно всегда было медленным и глючным - мне нужен был плавный эффект параллакса.

Итак, мое решение заключалось в реализации View.OnTouchListener. MotionEvent необходимо масштабировать, чтобы компенсировать разницу в ширине.

public class SyncScrollOnTouchListener implements View.OnTouchListener {

private final View syncedView;

public SyncScrollOnTouchListener(@NonNull View syncedView) {
    this.syncedView = syncedView;
}

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
    MotionEvent syncEvent = MotionEvent.obtain(motionEvent);
    float width1 = view.getWidth();
    float width2 = syncedView.getWidth();

    //sync motion of two view pagers by simulating a touch event
    //offset by its X position, and scaled by width ratio
    syncEvent.setLocation(syncedView.getX() + motionEvent.getX() * width2 / width1,
            motionEvent.getY());
    syncedView.onTouchEvent(syncEvent);
    return false;
}
}

Затем установите его на ViewPager

    sourcePager.setOnTouchListener(new SyncScrollOnTouchListener(targetPager));

Обратите внимание, что это решение будет работать, только если оба пейджера имеют одинаковую ориентацию. Если вам нужно, чтобы он работал для разных ориентаций - отрегулируйте syncEvent координату Y вместо X.

Есть еще одна проблема, которую мы должны принять во внимание - минимальная скорость и расстояние, при котором только один пейджер может сменить страницу.

Это можно легко исправить, добавив OnPageChangeListener на наш пейджер

sourcePager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset,
                                   int positionOffsetPixels) {
            //no-op
        }

        @Override
        public void onPageSelected(int position) {
            targetPager.setCurrentItem(position, true);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            //no-op
        }
    }); 
0 голосов
/ 20 декабря 2012

Вы пробовали beginFakeDrag()?

...