2015-09-27 16 views
19

Tôi có một RecyclerView với LinearLayoutManager theo hướng HORIZONTAL. Mỗi mục trong đó có thể có các yếu tố tương tác (bao gồm cả các chiều dọc ScrollView s). Có cách nào để dễ dàng thực hiện các RecyclerView bỏ qua bất kỳ nỗ lực nào của người dùng để cuộn hoặc trượt RecyclerView theo chiều ngang mà không chặn các sự kiện chạm vào trẻ em không?Cách tắt tính năng cuộn RecyclerView ngoại trừ lập trình

Tôi đang điều khiển theo chương trình cuộn của RecyclerView hoạt động tuyệt vời cho đến khi người dùng bẻ khóa.

Tôi đã thử một cái gì đó rất đơn giản, nơi mà ý tưởng là khi tôi gọi smoothScrollToPosition để đáp ứng với một số sự kiện, tôi cho phép di chuyển và tắt các sự kiện cảm ứng cho đến khi di chuyển lắng xuống. Như thế này:

private class NoScrollHorizontalLayoutManager extends LinearLayoutManager { 
    ScrollingTouchInterceptor interceptor = new ScrollingTouchInterceptor(); 
    protected boolean canScroll; 

    public NoScrollHorizontalLayoutManager(Context ctx) { 
     super(ctx, LinearLayoutManager.HORIZONTAL, false); 
    } 

    public RecyclerView.OnItemTouchListener getInterceptor() { 
     return interceptor; 
    } 

    @Override 
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { 
     canScroll = true; 
     super.smoothScrollToPosition(recyclerView, state, position); 
    } 

    @Override 
    public void onScrollStateChanged(int state) { 
     super.onScrollStateChanged(state); 
     if(state == RecyclerView.SCROLL_STATE_IDLE) { 
     canScroll = false; 
     } 
    } 

    @Override 
    public boolean canScrollHorizontally() { 
     return canScroll; 
    } 

    public class ScrollingTouchInterceptor implements RecyclerView.OnItemTouchListener { 
     @Override 
     public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { 
     return canScrollHorizontally(); 
     } 

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

     @Override 
     public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { 
     } 
    } 
    } 

Và sử dụng nó như thế này ..

NoScrollHorizontalLayoutManager layout = new NoScrollHorizontalLayoutManager(context); 
recycler.setLayoutManager(layout); 
recycler.addOnItemTouchListener(layout.getInterceptor()); 

mà thực sự gần công trình ... nhưng tôi vẫn có thể vít lên cuộn chương trình bằng cách chạm vào màn hình khi di chuyển trơn tru đang chuyển động. rõ ràng tôi đang thiếu một cái gì đó rõ ràng hoặc có một cách thông minh hơn nhiều để làm điều này.

CẬP NHẬT giải pháp phi RecyclerView đã được tìm thấy ở đây: How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?

/** 
* ViewPager that doesn't allow swiping. 
*/ 
public class NonSwipeableViewPager extends ViewPager { 

    public NonSwipeableViewPager(Context context) { 
    super(context); 
    } 

    public NonSwipeableViewPager(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent event) { 
    // Never allow swiping to switch between pages 
    return false; 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
    // Never allow swiping to switch between pages 
    return false; 
    } 
} 
+0

Tôi đã kết thúc bằng cách sử dụng một ViewPager thời trang cũ ... hoạt động hoàn hảo với ít mã hơn ... oh well. – danb

+0

Không hiểu bạn đang cố làm gì. –

+0

Đăng mã, cách bạn xử lý nó –

Trả lời

0
android:nestedScrollingEnabled="false" 

Làm một ở trên trong file xml, trong TAG RecyclerView.

+0

Điều đó không làm bất cứ điều gì không may là – danb

+0

giống ở đây, không có hiệu lực. Bạn có ý tưởng nào khác không? – Karoly

+0

android: nestedScrollingEnabled = "false" chức năng này là dành cho nếu bạn muốn sử dụng scrollview scroll thay vì recyclerview scroll .. – ZeroOne

0

Điều đầu tiên, tôi không nghĩ rằng điều này có thể đạt được không theo chương trình.

Cách 1: Đơn giản - Tắt chế độ xem khác dựa trên lần chạm.

Nếu người dùng chạm vào phụ huynh, hãy vô hiệu hóa cuộn chế độ xem con. ngược lại cũng

Piece of code để làm điều này

recyclerView.setOnTouchListener(new View.OnTouchListener() 
{ 
    public boolean onTouch(View p_v, MotionEvent p_event) 
    { 
     yourChildView.getParent().requestDisallowInterceptTouchEvent(false); 
     return false; 
    } 
}); 

Way 2: Vì bạn đang gặp vấn đề nhỏ trong việc thực hiện của bạn. Nếu bạn đăng nó, ai đó cũng có thể sửa nó.

+0

Tôi nghĩ bạn hiểu lầm. Vấn đề là tôi không muốn người dùng có thể vuốt chế độ xem của người tái chế. Tôi chỉ muốn nó di chuyển khi tôi nói với nó trong mã. Tất cả các quan điểm của trẻ em nên hành động bình thường (và chúng có thể) – danb

+0

vâng có thể. Nhìn vào nó. Bạn có thể thử một điều nữa không. Đặt trình nghe cảm ứng cho 'viewpager' và trả về true luôn –

+0

Giải pháp trình xem tôi đã thêm vào câu trả lời hoạt động như dự định. Nó đang được sản xuất bây giờ – danb

0

Ghi đè trênInterceptTouchEvent bạn tránh dừng hoạt động nhấp chuột.

@Override 
public boolean onInterceptTouchEvent(MotionEvent e) { 
    return false; 
} 
0
recyclerView.setOnTouchListener(new View.OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      return true; 
     } 
    }); 
+0

Điều này cũng vô hiệu hóa bất kỳ sự kiện cảm ứng nào trên người xem trong chế độ xem của người tái chế. –

0
recyclerView.setNestedScrollingEnabled(false); 

Để biết thêm thông thấy documentation.

0

Điều này mang lại hiệu quả của tính liên tục.

recyclerView.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       int action = event.getAction(); 
       if (action == MotionEvent.ACTION_DOWN) { 
        recyclerView.smoothScrollToPosition(position); 
        return true; 
       } else if (action == MotionEvent.ACTION_UP) { 
        recyclerView.smoothScrollToPosition(position); 
        return true; 
       } 
       return false; 
      } 
     }); 
Các vấn đề liên quan