2011-10-04 96 views
1

我有两个ViewPagers - Pager1和Pager2。我为Pager1添加了一个OnPageChangeListener,并在onPageScrolled回调中调用了Pager2.scrollTo(x,y)来移动它。两个ViewPage都能顺利滚动并同步,但问题在于Pager2的内容不会改变。我用LogCat检查它 - 为Pager2的instantiateItem()根本没有被调用。Android viewpager同步滚动

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

回答

0

你试过beginFakeDrag()

0

最适合我的解决方案是在ViewPager个实例之间通过MotionEvent,OnTouchListener。尝试假拖,但它总是滞后和越野车 - 我需要一个平滑,类似视差的效果。

所以,我的解决方案是实施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 
     } 
    });