5

私はビューページャーを持っていて、片方に縦と横のrecyclerviewを含む2つの別々の断片があります。子リサイクラビューが最後の項目にスクロールしたときにViewPagerページングを無効にする

水平リサイクラビューを最後のアイテムにスクロールし、さらにスワイプしようとすると、ビューページは次のページにスクロールします。私はこれが起こることを望んでいない。私は水平リサイクルビューをオーバースケールしようとすると、ビューページのページングを無効にしたいと思います。

ただし、他の場所でスワイプすると、ビューページのページングを無効にしたくないです。たとえば、私が垂直のrecyclerviewまたは親フラグメント内の空きスペースをスワイプすると、ビューページャがページを変更する原因になります。

私はin this SO questionを読んで、ビューページャのページングを無効にする方法。また、 this SO questionは、子ビューポートがある点で似ていますが、私は水平なrecyclerviewでそれを複製しようとしていません。

ここではいくつかの構造です:私はページングを無効にすることができます

カスタムviewpager(SO上記のリンク最初からそれを取った):

public class CustomViewPager extends ViewPager { 

private boolean enabled; 

public CustomViewPager(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    this.enabled = true; 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    if (this.enabled) { 
     return super.onTouchEvent(event); 
    } 

    return false; 
} 

@Override 
public boolean onInterceptTouchEvent(MotionEvent event) { 
    if (this.enabled) { 
     return super.onInterceptTouchEvent(event); 
    } 

    return false; 
} 

public void setPagingEnabled(boolean enabled) { 
    this.enabled = enabled; 
} } 

私はontouchlistenerを設定し、水平recyclerview(第2に似ては、 SO)上記のリンク:

horizontalRecyclerView.setOnTouchListener(new View.OnTouchListener() { 
       @Override 
       public boolean onTouch(View v, MotionEvent event) { 
        switch(event.getAction()){ 
         case MotionEvent.ACTION_MOVE: 
          customViewPager.setPagingEnabled(false); 
          break; 
         case MotionEvent.ACTION_UP: 
          customViewPager.setPagingEnabled(true); 
          break; 
        } 
        return false; 
       } 
      }); 

エクストラ所見:私は時々私の場合、長押しことに気づいたが私がスワイプする前に、horizo​​ntal recyclerviewはビューページャの次のページには行きません。しかし、すばやくスワイプすると、ビューページは次のページに移動します。

誰でもこれを行う適切な方法を知っていますか?

何か助けていただければ幸いです。

+0

すべての解決策が見つかりました。私は同じものを探しています –

答えて

12

ここが解決策です。

requestDisallowInterceptTouchEvent() 

このメソッドでは、親の移動は許可されません。ビューページのタッチイベントを停止します。

がRecyclerView項目

mGestureDetector = new GestureDetector(itemView.getContext(), new GestureListener()); 

/** 
* Prevents the view pager from switching tabs when scrolling the carousel 
*/ 
private class TouchListener implements RecyclerView.OnItemTouchListener { 

    @Override 
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { 
     mGestureDetector.onTouchEvent(e); 
     return false; 
    } 
} 

ためのタッチリスナーを作成し、タッチを禁止GestureListenerを実装:垂直方向のスクロールは、もはや私が代わりにこれをしなかった作業で問題を処理するために

horizontalRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { 
     @Override 
     public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { 
      int action = e.getAction(); 
      switch (action) { 
       case MotionEvent.ACTION_MOVE: 
        rv.getParent().requestDisallowInterceptTouchEvent(true); 
        break; 
      } 
      return false; 
     } 

     @Override 
     public void onTouchEvent(RecyclerView rv, MotionEvent e) { 

     } 

     @Override 
     public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { 

     } 
    }); 
+1

スーパー、おかげで助けて! – JasonWyatt

+0

これは問題なく動作しますが、recyclerviewは最後の項目までスクロールされます。最初の項目を表示する必要があります。 –

+0

私は本当に動作を防止するために、すべてのイベントに対して要求を使用しなければなりませんでした。 public boolean onInterceptTouchEvent(RecyclerView rv、MotionEvent e){ rv.getParent()。requestDisallowInterceptTouchEvent(true); falseを返します。 } –

1

水平スクロールが検出されたときのイベント:

private class GestureListener extends SimpleOnGestureListener { 
    private final int Y_BUFFER = 10; 

    @Override 
    public boolean onDown(MotionEvent e) { 
     // Prevent ViewPager from intercepting touch events as soon as a DOWN is detected. 
     // If we don't do this the next MOVE event may trigger the ViewPager to switch 
     // tabs before this view can intercept the event. 
     mRecyclerView.requestDisallowInterceptTouchEvent(true); 
     return super.onDown(e); 
    } 

    @Override 
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
     if (Math.abs(distanceX) > Math.abs(distanceY)) { 
      // Detected a horizontal scroll, prevent the viewpager from switching tabs 
      mRecyclerView.requestDisallowInterceptTouchEvent(true); 
     } else if (Math.abs(distanceY) > Y_BUFFER) { 
      // Detected a vertical scroll of large enough magnitude so allow the the event 
      // to propagate to ancestor views to allow vertical scrolling. Without the buffer 
      // a tab swipe would be triggered while holding finger still while glow effect was 
      // visible. 
      mRecyclerView.requestDisallowInterceptTouchEvent(false); 
     } 
     return super.onScroll(e1, e2, distanceX, distanceY); 
    } 
} 
関連する問題