Как отключить прокрутку RecyclerView, кроме программных

У меня есть RecyclerView с LinearLayoutManager в ориентации HORIZONTAL . Каждый элемент в нем может иметь интерактивные элементы (включая вертикальные ScrollView s). Есть ли способ легко заставить RecyclerView игнорировать любые попытки пользователя прокручивать или перемещать RecyclerView горизонтали, не перехватывая события касания к детям?

Я программно контролирую прокрутку RecyclerView которая отлично работает, пока пользователь не отбросит ее.

Я пробовал что-то очень простое, когда идея заключается в том, что я вызываю smoothScrollToPosition в ответ на какое-то событие, я разрешаю прокрутку и отключать события касания до тех пор, пока свиток не опустится. Как это:

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

И используйте его вот так ..

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

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

ОБНОВЛЕНИЕ решение non-RecyclerView было найдено здесь: Как отключить пейджинг, проверив пальцем в ViewPager, но все же сможете прокручивать программно?

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

Solutions Collecting From Web of "Как отключить прокрутку RecyclerView, кроме программных"

 android:nestedScrollingEnabled="false" 

Выполните вышеуказанное в файле xml в TAG RecyclerView.

Во-первых, я не думаю, что это возможно не программно.

Путь 1: Простой – отключить другое представление, основанное на касании.

Если пользователь прикасается к родительскому, отключите прокрутку дочерних просмотров. Наоборот, наоборот

Часть кода для этого

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

Способ 2: Поскольку у вас небольшие проблемы в вашей реализации. Если вы публикуете его, кто-то может это исправить.

Переопределяя onInterceptTouchEvent, вы избегаете остановки при нажатии.

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

Для получения дополнительной информации см. Документацию .

Это дает эффект непрерывности.

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