Фон
Рассмотрим следующий сценарий:
- Есть 2 viewPagers, каждый из которых имеет разную ширину и высоту, но оба имеют одинаковое количество страниц.
- перетаскивание нужно перетащить другим, поэтому эффект подобен эффекту "параллакса".
- то же, что и # 2, но для другого viewPager.
- также существует механизм автоматического переключения между диспетчерами, поэтому каждые 2 секунды он автоматически переключается на следующую страницу (и если на последней странице переключается на первый).
Проблема
Я думаю, что у меня есть некоторые функциональные возможности, но у него есть некоторые проблемы:
- Это просто простой XML. ничего особенного здесь.
- Я использовал 'OnPageChangeListener', и там, в 'onPageScrolled', я использовал поддельное перетаскивание. Проблема в том, что если перетаскивание пользователя останавливается около середины страницы (таким образом активируется автоматическая прокрутка viewPager влево/вправо), поддельное перетаскивание теряет синхронизацию, и могут возникать странные вещи: неправильная страница или даже пребывание между страницами...
- В настоящее время я не обрабатываю другой viewPager с перетаскиванием пользователя, но это тоже может быть проблемой.
-
Это может быть проблемой, когда мне удается решить проблему №2 (или # 3). На данный момент я использую обработчик, который использует runnable и вызывает эту команду внутри:
mViewPager.setCurrentItem((mViewPager.getCurrentItem() + 1) % mViewPager.getAdapter().getCount(), true);
Что я пробовал
Я пробовал этот пост, но он не сработал, так как он получил те же проблемы, когда пользователь перетаскивал останавливается, прежде чем закончить переключение на другую страницу.
Только одно подобное решение работает с одним ViewPager ( здесь), но мне нужно работать с 2 ViewPagers, каждый влияет на другой.
Итак, я попытался сделать это сам: предположим, что один viewPager - это "viewPager", а другой (который должен следовать "viewPager" ) - "viewPager2", вот что я сделал:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
int lastPositionOffsetPixels=Integer.MIN_VALUE;
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
if (!viewPager2.isFakeDragging())
viewPager2.beginFakeDrag();
if(lastPositionOffsetPixels==Integer.MIN_VALUE) {
lastPositionOffsetPixels=positionOffsetPixels;
return;
}
viewPager2.fakeDragBy((lastPositionOffsetPixels - positionOffsetPixels) * viewPager2.getWidth() / viewPager.getWidth());
lastPositionOffsetPixels = positionOffsetPixels;
}
@Override
public void onPageSelected(final int position) {
if (viewPager2.isFakeDragging())
viewPager2.endFakeDrag();
viewPager2.setCurrentItem(position,true);
}
@Override
public void onPageScrollStateChanged(final int state) {
}
});
Я решил использовать фальшивое перетаскивание, потому что даже документы говорят, что это может быть полезно для этого точный сценарий:
Поддельное перетаскивание может быть полезно, если вы хотите синхронизировать движение ViewPager с сенсорной прокруткой другого вида, в то время как позволяя ViewPager управлять движением привязки и срабатыванием. (например, вкладки прокрутки параллакса.) Вызвать fakeDragBy (float) для имитации фактическое движение движения. Вызов endFakeDrag() для завершения поддельного перетаскивания и если необходимо.
Чтобы упростить тестирование, здесь больше кода:
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
final ViewPager viewPager2 = (ViewPager) findViewById(R.id.viewPager2);
viewPager.setAdapter(new MyPagerAdapter());
viewPager2.setAdapter(new MyPagerAdapter());
//do here what needed to make "viewPager2" to follow dragging on "viewPager"
}
private class MyPagerAdapter extends PagerAdapter {
int[] colors = new int[]{0xffff0000, 0xff00ff00, 0xff0000ff};
@Override
public int getCount() {
return 3;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
@Override
public boolean isViewFromObject(final View view, final Object object) {
return (view == object);
}
@Override
public Object instantiateItem(final ViewGroup container, final int position) {
TextView textView = new TextView(MainActivity.this);
textView.setText("item" + position);
textView.setBackgroundColor(colors[position]);
textView.setGravity(Gravity.CENTER);
final LayoutParams params = new LayoutParams();
params.height = LayoutParams.MATCH_PARENT;
params.width = LayoutParams.MATCH_PARENT;
params.gravity = Gravity.CENTER;
textView.setLayoutParams(params);
textView.setTextColor(0xff000000);
container.addView(textView);
return textView;
}
}
activity_main
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="viewPager:"/>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="viewPager2:"/>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager2"
android:layout_width="match_parent"
android:layout_height="100dp"/>
</LinearLayout>
Вопрос
Код работает очень хорошо. Мне просто нужно знать, чего не хватает, чтобы избежать проблем с перетаскиванием (пользователем)? Другие проблемы могут иметь более простые решения.