Android viewpager同步滚动

时间:2011-10-04 20:23:34

标签: android scroll views synchronized android-viewpager

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

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

2 个答案:

答案 0 :(得分:0)

您是否尝试过beginFakeDrag()

答案 1 :(得分:0)

对我来说最有效的解决方案是在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
        }
    }); 
相关问题