2011-10-04 6 views
1

두 개의 ViewPagers - Pager1과 Pager2가 있습니다. OnPageChangeListener를 Pager1에 추가하고 onPageScrolled 콜백에서 Pager2.scrollTo (x, y)를 호출하여 이동합니다. 두 ViewPager는 부드럽게 스크롤하고 동기화되지만 Pager2의 내용이 변경되지 않는 문제가 있습니다. 내가 LogCat - Pager2에 대한 instantiateItem() 전혀 호출되지 않습니다 그것을 확인했습니다.안드로이드 뷰 페이지 동기화 스크롤

임시 해결책으로 Pager1의 onPageSelected() 콜백에 Pager2.setCurrentItem()을 추가했습니다. 두 뷰를 스크롤하는 동안 픽셀과 동기화되지 않습니다. 실제 ViewPager 클래스를 재정의하지 않고도이 효과를 얻을 수있는 방법이 있는지 궁금합니다.

답변

0

beginFakeDrag()을 사용해 보셨습니까?

0

가장 좋은 해결책은 MotionEventOnTouchListenerViewPager 건 사이에 전달하는 것이 었습니다. 가짜 드래그를 시도했지만 항상 느리고 버그가 많았습니다. 나는 시차와 같은 부드러운 효과가 필요했습니다.

내 솔루션은 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)); 

참고로 설정합니다. 다른 방향으로 작업해야하는 경우 - X 대신 syncEvent Y 좌표를 조정하십시오.

한 번만 호출기가 페이지를 변경할 수있는 최소 이륙 속도와 거리를 고려해야 할 문제가 하나 더 있습니다.

그것은 쉽게 우리 호출기로 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 
     } 
    });