5

Tôi có một người xem và trong một trong các đoạn tôi có hai đoạn riêng biệt chứa một recyclerview dọc và ngang tương ứng.Vô hiệu hóa phân trang ViewPager khi con recyclerview cuộn đến mục cuối

Khi tôi cuộn recyclerview ngang đến mục cuối cùng và cố gắng vuốt xa hơn, chế độ xem cuộn sẽ cuộn đến trang tiếp theo. Tôi không muốn điều này xảy ra. Tôi muốn vô hiệu hóa phân trang của người xem khi tôi cố gắng overscroll recyclerview ngang.

Tuy nhiên, tôi không muốn tắt phân trang của người xem khi tôi vuốt bất kỳ nơi nào khác. Ví dụ: Nếu tôi đã vuốt trên recyclerview theo chiều dọc hoặc bất kỳ khoảng trống nào trong đoạn gốc, nó vẫn sẽ khiến người xem thay đổi trang.

Tôi đọc in this SO question, cách tắt phân trang của người xem. Ngoài ra this SO question là tương tự trong đó có một người xem trẻ em, tuy nhiên tôi đã không có thành công cố gắng để tái tạo với một recyclerview ngang.

Dưới đây là một số cấu trúc:

Các ViewPager tùy chỉnh cho phép tôi để vô hiệu hóa phân trang (lấy nó từ đầu tiên SO liên kết ở trên):

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; 
} } 

Đối với recyclerview ngang tôi đặt một ontouchlistener (tương tự như thứ hai SO liên kết ở trên):

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; 
       } 
      }); 

quan sát thêm: tôi nhận thấy rằng đôi khi nếu tôi dài bấm recyclerview ngang trước khi tôi swipe nó sẽ không đi đến trang tiếp theo của viewpager. Tuy nhiên, nếu tôi vuốt nhanh, chế độ xem sẽ chuyển sang trang tiếp theo.

Có ai biết cách thích hợp để thực hiện việc này không?

Mọi trợ giúp đều được đánh giá cao.

+0

bất kỳ giải pháp nào được tìm thấy. Tôi đang tìm kiếm cùng một –

Trả lời

12

Đây là giải pháp.

requestDisallowInterceptTouchEvent() 

Phương pháp này sẽ không cho phép cha mẹ di chuyển. Nó dừng sự kiện 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

Siêu hữu ích, cảm ơn! – JasonWyatt

+0

cái này hoạt động tốt nhưng recyclerview được cuộn đến mục cuối cùng. nên hiển thị mục đầu tiên. –

+0

Tôi đã phải sử dụng yêu cầu ... cho tất cả các sự kiện để thực sự ngăn chặn hành vi. công khai boolean onInterceptTouchEvent (RecyclerView rv, MotionEvent e) { rv.getParent(). RequestDisallowInterceptTouchEvent (true); trả về false; } –

1

Để xử lý các vấn đề với cuộn dọc không còn làm việc tôi đã làm điều này thay vì:

Tạo một người biết lắng nghe cảm ứng cho mục 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; 
    } 
} 

Và thực hiện một GestureListener không cho phép liên lạc sự kiện khi cuộn ngang được phát hiện:

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); 
    } 
} 
Các vấn đề liên quan