5

У меня есть viewpager и внутри одного из фрагментов у меня есть два отдельных фрагмента, содержащих вертикальный и горизонтальный recyclerview соответственно.Отключить пейджинг ViewPager, когда дочерний recyclerview прокручивается до последнего элемента

Когда я просматриваю горизонтальный recyclerview до последнего элемента и пытаюсь прокрутить дальше, viewpager прокручивается на следующую страницу. Я не хочу, чтобы это произошло. Я хочу отключить подкачку viewpager, когда я пытаюсь перекрыть горизонтальный recyclerview.

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

Я прочитал in this SO question, как отключить пейджинг зрителя. Также this SO question похож на то, что есть дочерний viewpager, однако у меня не было успеха, пытаясь воспроизвести его с помощью горизонтального 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; 
} } 

Для горизонтального recyclerview я установить ontouchlistener (аналогично второму 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; 
       } 
      }); 

Дополнительные замечания: я заметил, что иногда, если я долго нажмите горизонтальный recyclerview, прежде чем я проведу, он не перейдет на следующую страницу viewpager. Однако, если я быстро проведу, просмотрщик перейдет на следующую страницу.

Кто-нибудь знает, как правильно это сделать?

Любая помощь приветствуется.

+0

любое решение было найдено. Я ищу то же самое –

ответ

12

Это решение.

requestDisallowInterceptTouchEvent() 

Этот метод не позволит родителям перемещаться. Он останавливает событие touchpager touch.

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); return false; } –

1

Для того, чтобы справиться с проблемой с вертикальной прокруткой больше не работает, я сделал это вместо того, чтобы:

Создать сенсорную слушателя для элемента 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, который запрещает прикосновение события, когда обнаружены горизонтальные свитки:

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); 
    } 
} 
Смежные вопросы