Android viewpager 同步滚动

Posted

技术标签:

【中文标题】Android viewpager 同步滚动【英文标题】:Android viewpager synchronized scrolling 【发布时间】:2011-10-04 20:23:34 【问题描述】:

我有两个 ViewPager——Pager1 和 Pager2。我向 Pager1 添加了一个 OnPageChangeListener 并在 onPageScrolled 回调中调用 Pager2.scrollTo(x, y) 来移动它。两个 ViewPager 都可以平滑滚动并且是同步的,但问题是 Pager2 的内容没有改变。我用 LogCat 检查了它——根本没有调用 Pager2 的 instantiateItem() 。

作为一种解决方法,我将 Pager2.setCurrentItem() 添加到 Pager1 的 onPageSelected() 回调中。虽然这确实滚动了两个视图,但它不与像素同步。我想知道是否有一种方法可以实现这种效果而无需覆盖实际的 ViewPager 类。

【问题讨论】:

【参考方案1】:

最适合我的解决方案是在 OnTouchListener 中的 MotionEventViewPager 实例之间传递。尝试过假拖动,但它总是很慢而且有问题——我需要一个平滑的、类似视差的效果。

所以,我的解决方案是实现View.OnTouchListenerMotionEvent 必须缩放以补偿宽度差异。

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

【讨论】:

【参考方案2】:

你试过beginFakeDrag()吗?

【讨论】:

以上是关于Android viewpager 同步滚动的主要内容,如果未能解决你的问题,请参考以下文章

Android内存优化之ViewPager的内存优化

Android CoordinatorLayout + AppbarLayout + Viewpager 总是滚动

同步 ViewPager 中的所有 ListView

滚动条 viewPager

Viewpager Fragment中的Android Listview-不滚动

Android Studio 无法解析 fragmentActivity 和 ViewPager 导入