【发布时间】:2021-05-28 05:42:50
【问题描述】:
背景
考虑以下场景:
- 有 2 个 viewPager,每个具有不同的宽度和高度,但它们的页数完全相同。
- 拖动一个应该拖动另一个,所以效果就像“视差”效果。
- 与 #2 相同,但用于另一个 viewPager。
- viewpager 之间还有一种自动切换机制,因此它会每 2 秒自动切换到下一页(如果在最后一页,则切换回第一页)。
问题
我认为我的某些功能可以正常工作,但存在一些问题:
- 这只是简单的 XML。这里没什么特别的。
- 我使用了“OnPageChangeListener”,在“onPageScrolled”中,我使用了假拖动。问题是,如果用户的拖动在页面中间附近停止(从而激活了向左/向右自动滚动 viewPager),虚假的拖动会失去同步,并且可能会发生奇怪的事情:错误的页面甚至停留在页面之间。 ..
- 目前,我不处理其他 viewPager 与用户的拖动,但这也可能是一个问题。
-
当我成功解决 #2(或 #3)时,这可能是一个问题。目前,我正在使用一个处理程序,该处理程序使用可运行并在内部调用此命令:
mViewPager.setCurrentItem((mViewPager.getCurrentItem() + 1) % mViewPager.getAdapter().getCount(), true);
我尝试过的
我尝试过this post,但效果不佳,因为当用户在完成切换到另一个页面之前停止拖动时,它会遇到同样的问题。
只有一个有效的类似解决方案是使用单个 ViewPager (here),但我需要使用 2 个 ViewPager,每个 ViewPager 都会影响另一个。
所以我自己尝试过:假设一个 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) {
}
});
我选择使用假拖动,因为 even the docs 说它可能对完全相同的场景有用:
如果您想同步 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's 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>
问题
代码几乎运行良好。我只需要知道,为了避免(由用户)停止拖动的问题,缺少什么? 其他问题可能有更简单的解决方案。
【问题讨论】:
标签: android android-viewpager parallax