2

В моей Android-приложение я следующее расположение:Отправка событий из Scrollview к подстилающей ViewPager

<CustomRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
> 

<android.support.v4.view.ViewPager 
    android:id="@+id/image_viewpager" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    /> 

<OverScrollBounceScrollView 
    android:id="@+id/scrollview" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fillViewport="true" 
    > 

    <LinearLayout 
     android:id="@+id/user_profile_scroll_content" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical" 
     > 

     <RelativeLayout 
      android:id="@+id/dummy_viewport" 
      android:layout_width="match_parent" 
      android:layout_height="350dp" 
      > 

     </RelativeLayout> 

     <LinearLayout 
      android:id="@+id/scroll_content" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:orientation="vertical" 
      android:background="@android:color/white" 
      > 

      ...some content 

     </LinearLayout> 
    </LinearLayout> 
</OverScrollBounceScrollView> 
</CustomRelativeLayout> 

Это выглядит примерно так:

http://i.stack.imgur.com/lzL5u.png

Мои цели:

  1. Когда я прокручиваю по Y-направлению, я хочу, чтобы scrollview захватил и прокрутил нормально
  2. Когда я прокручиваю в X-направлении я хочу ViewPager под Scrollview взять над

Проблема теперь в том, что Scrollview берет на себя все события и ViewPager не может быть достигнуто на всех.

Любые идеи о том, как это решить?

ответ

4

Для тех, кто заинтересован в ответе на этот вопрос или имеет похожие проблемы, вот как я его решил.

Прежде всего, общий подход заключается в создании пользовательского представления, которое перехватывает определенные события касания и делегирует их правильным дочерним элементам.

В моем случае viewpager должен перехватывать горизонтальные жесты, а прокрутка - Наверху viewpager должен получать только вертикальные прокрутки-события. Одним из особых требований для меня было то, что viewpager также должен перехватывать только сенсорные события в пределах определенной границы, а именно фиктивный видовой экран, который является дочерним внутри наложением прокрутки.

В пользовательском классе макета один должен переопределить метод onInterceptTouchEvent() в сочетании с методом onTouchEvent():

@Override 
public boolean onInterceptTouchEvent (MotionEvent event) { 
    // 1.) remember DOWN event ALWAYS as this is important start for every gesture 
    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      mInitialX = event.getX(); 
      mInitialY = event.getY(); 
      mInitialDownEvent = MotionEvent.obtainNoHistory(event); 
      mIsDownEventDispatched = false; 
      break; 
     case MotionEvent.ACTION_MOVE: 
      final float x = event.getX(); 
      final float y = event.getY(); 
      final int yDiff = (int) Math.abs(y - mInitialY); 
      final int xDiff = (int) Math.abs(x - mInitialX); 
      calculateDelegatesHitRectangle(); 
      if(xDiff > mTouchSlop && mDelegateBounds.contains((int)event.getX(), (int)event.getY())){ 
       // 2.) if we scroll more in X-direction AND we are within the bounds of our delegatinView 
       //  then INTERCEPT event here, so this views onTouch will be called 
       Log.d("hitrect", "HITRECT--- TOP: " + mDelegateBounds.top + " BOTTOM: " + mDelegateBounds.bottom); 
       return true; 
      } 
      break; 
    } 

    return super.onInterceptTouchEvent(event); 

} 


@Override 
public boolean onTouchEvent(MotionEvent event) { 

    // 3.) we receive ALL following event after X-Scroll has been intercepted 
    //  but the DOWN event was handled by this view so we have to dispatch the remembered down event 
    //  so the dispatch-target has a valid start for the scroll-gesture 
    if(!mIsDownEventDispatched){ 
     mDispatchTargetView.dispatchTouchEvent(mInitialDownEvent); 
     mIsDownEventDispatched = true; 
    } 
    mDispatchTargetView.dispatchTouchEvent(event); 
    Log.d("touch", "ROOT: onTouchEvent after Intercept " + event.getActionMasked()); 
    return true; 
} 

Как вы можете видеть, я всегда проверяю и сохранить понижающий событие в член класса, и как только обнаружено движение, я проверяю, выполняется ли оно в x-направлении (для viewpager). Затем перехватывается. Мой метод calculateDelegatesHitRectangle() в этом случае проверяет только ли я в пределах, где я хочу, кроме событий касания.

В onTouch я только перенаправляю перехваченный горизонтальный жест на мой viewpager, который вводится в этот пользовательский вид через сеттер. Чтобы иметь правильный жест, мне также нужно перенаправить перехваченное событие DOWN.

Из моего кода активности я просто установить цель доставки и вид делегата:

dispatchAwareLayout.setDispatchTargetView(mImageViewPager); 
dispatchAwareLayout.setDelegateView(mDummyViewport); 
Смежные вопросы