Как отключить прокрутку RecyclerView?

Я не могу отключить прокрутку в RecyclerView. Я пробовал называть rv.setEnabled(false), но я все еще могу прокручивать.

Как отключить прокрутку?

Ответ 1

Для этого вы должны переопределить layoutmanager вашего recycleview. Таким образом, он будет отключать прокрутку, ни одна из других функций. Вы по-прежнему сможете обрабатывать клики или любые другие события касания. Например: -

Оригинал:

 public class CustomGridLayoutManager extends LinearLayoutManager {
 private boolean isScrollEnabled = true;

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

 public void setScrollEnabled(boolean flag) {
  this.isScrollEnabled = flag;
 }

 @Override
 public boolean canScrollVertically() {
  //Similarly you can customize "canScrollHorizontally()" for managing horizontal scroll
  return isScrollEnabled && super.canScrollVertically();
 }
}

Здесь, используя флаг isScrollEnabled, вы можете временно включать/отключать функции прокрутки вашего временного списка.

Также:

Просто переопределите существующую реализацию, чтобы отключить прокрутку и разрешить щелчок.

 linearLayoutManager = new LinearLayoutManager(context) {
 @Override
 public boolean canScrollVertically() {
  return false;
 }
};

Ответ 2

Реальный ответ

recyclerView.setNestedScrollingEnabled(false);

Дополнительная информация в документации

Ответ 3

Это немного хакерское решение, но оно работает; вы можете включить/отключить прокрутку в RecyclerView.

Это пустой RecyclerView.OnItemTouchListener кража каждого события касания, таким образом отключая цель RecyclerView.

public class RecyclerViewDisabler implements RecyclerView.OnItemTouchListener {

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        return true;
    }

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

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

Используя его:

RecyclerView rv = ...
RecyclerView.OnItemTouchListener disabler = new RecyclerViewDisabler();

rv.addOnItemTouchListener(disabler);        // disables scolling
// do stuff while scrolling is disabled
rv.removeOnItemTouchListener(disabler);     // scrolling is enabled again 

Ответ 4

РЕАЛЬНЫЙ РЕАЛЬНЫЙ ответ: Для API 21 и выше:

Код Java не требуется. Вы можете установить android:nestedScrollingEnabled="false" в XML:

<android.support.v7.widget.RecyclerView
     android:id="@+id/recycler"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:clipToPadding="true"
     android:nestedScrollingEnabled="false"
     tools:listitem="@layout/adapter_favorite_place">

Ответ 5

Это работает для меня:

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

Ответ 6

Создать класс, который расширяет класс RecyclerView

public class NonscrollRecylerview extends RecyclerView {

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

    public NonscrollRecylerview(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public NonscrollRecylerview(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
    }
}

Это отключит событие прокрутки, но не события щелчка

Используйте это в своем XML, сделайте следующее:

  <com.yourpackage.xyx.NonscrollRecylerview 
     ...
     ... 
  />

Ответ 7

Если вы просто отключите только функции прокрутки RecyclerView вы можете использовать setLayoutFrozen(true); метод RecyclerView. Но нельзя отключить событие touch.

your_recyclerView.setLayoutFrozen(true);

Ответ 8

Вы можете отключить прокрутку, заморозив RecyclerView.

Заморозить: recyclerView.setLayoutFrozen(true)

Чтобы разморозить: recyclerView.setLayoutFrozen(false)

Ответ 10

recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
            // Stop only scrolling.
            return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING;
        }
    });

Ответ 11

Разверните LayoutManager и переопределите canScrollHorizontally() и canScrollVertically(), чтобы отключить прокрутку.

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

  private void clampRecyclerViewScroll(final RecyclerView recyclerView)
  {
    recyclerView.getAdapter().registerAdapterDataObserver(new RecyclerView.AdapterDataObserver()
    {
      @Override
      public void onItemRangeInserted(int positionStart, int itemCount)
      {
        super.onItemRangeInserted(positionStart, itemCount);
        // maintain scroll position at top
        if (positionStart == 0)
        {
          RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
          if (layoutManager instanceof GridLayoutManager)
          {
            ((GridLayoutManager) layoutManager).scrollToPositionWithOffset(0, 0);
          }else if(layoutManager instanceof LinearLayoutManager)
          {
            ((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(0, 0);
          }
        }
      }
    });
  }

Ответ 12

Я знаю, что на это уже есть принятый ответ, но решение не учитывает сценарий использования, с которым я столкнулся.

Мне особенно нужен был элемент заголовка, который можно было нажимать, но при этом отключить механизм прокрутки в RecyclerView. Это можно сделать с помощью следующего кода:

recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
                            @Override
     public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
         return e.getAction() == MotionEvent.ACTION_MOVE;
     }

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

     }

     @Override
     public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
});

Ответ 13

Написал версию kotlin:

class NoScrollLinearLayoutManager(context: Context?) : LinearLayoutManager(context) {
    private var scrollable = true

    fun enableScrolling() {
        scrollable = true
    }

    fun disableScrolling() {
        scrollable = false
    }

    override fun canScrollVertically() =
            super.canScrollVertically() && scrollable


    override fun canScrollHorizontally() =
            super.canScrollVertically()

 && scrollable
}

использование:

recyclerView.layoutManager = NoScrollLinearLayoutManager(context)
(recyclerView.layoutManager as NoScrollLinearLayoutManager).disableScrolling()

Ответ 14

По какой-то причине ответ @Alejandro Gracia начинает работать только через несколько секунд. Я нашел решение, которое мгновенно блокирует RecyclerView:

recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                return true;
            }
            @Override
            public void onTouchEvent(RecyclerView rv, MotionEvent e) {
            }
            @Override
            public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
            }
        });

Ответ 15

Переопределите onTouchEvent() и onInterceptTouchEvent() и верните false, если вам вообще не нужен OnItemTouchListener. Это не отключает OnClickListeners ViewHolders.

public class ScrollDisabledRecyclerView extends RecyclerView {
    public ScrollDisabledRecyclerView(Context context) {
        super(context);
    }

    public ScrollDisabledRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ScrollDisabledRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        return false;
    }
}

Ответ 16

в XML: -

Можете добавить

android:nestedScrollingEnabled="false"

в дочернем репозитории XML файл макета RecyclerView

или же

в Java: -

childRecyclerView.setNestedScrollingEnabled(false);

к вашему RecyclerView в Java-коде.

Использование ViewCompat (Java): -

childRecyclerView.setNestedScrollingEnabled(false); будет работать только в android_version> 21 устройстве. для работы на всех устройствах используйте следующие

ViewCompat.setNestedScrollingEnabled(childRecyclerView, false);

Ответ 17

Вы можете добавить эту строку после установки адаптера

ViewCompat.setNestedScrollingEnabled(recyclerView, false);

Теперь ваш recyclerview будет работать с плавной прокруткой

Ответ 18

Я борюсь в этой проблеме в течение часа, Поэтому я хотел бы поделиться своим опытом, Для решения layoutManager это нормально, но если вы хотите повторно использовать прокрутку, то повторитель вернется к началу.

Лучшее решение пока (по крайней мере для меня) использует метод @Zsolt Safrany, но добавляет getter и setter, поэтому вам не нужно удалять или добавлять OnItemTouchListener.

Как следует

public class RecyclerViewDisabler implements RecyclerView.OnItemTouchListener {

    boolean isEnable = true;

    public RecyclerViewDisabler(boolean isEnable) {
        this.isEnable = isEnable;
    }

    public boolean isEnable() {
        return isEnable;
    }

    public void setEnable(boolean enable) {
        isEnable = enable;
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        return !isEnable;
    }

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

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

Использование

RecyclerViewDisabler disabler = new RecyclerViewDisabler(true);
feedsRecycler.addOnItemTouchListener(disabler);

// TO ENABLE/DISABLE JUST USE THIS
disabler.setEnable(enable);

Ответ 19

Просто добавьте это в свой recycleview в xml

 android:nestedScrollingEnabled="false"

как это

<android.support.v7.widget.RecyclerView
                    android:background="#ffffff"
                    android:id="@+id/myrecycle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:nestedScrollingEnabled="false">

Ответ 20

Существует очень простой ответ.

LinearLayoutManager lm = new LinearLayoutManager(getContext()) {
                @Override
                public boolean canScrollVertically() {
                    return false;
                }
            };

Приведенный выше код отключает вертикальную прокрутку RecyclerView.

Ответ 21

Вот как я это сделал с привязкой данных:

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:clipChildren="false"
                android:onTouch="@{(v,e) -> true}"/>

Вместо "true" я использовал логическую переменную, которая была изменена на основе условия, так что просмотр recycler переключился бы между отключением и включением.

Ответ 22

Взаимодействовал с фрагментом, который содержит несколько RecycleView, поэтому мне нужна только одна полоса прокрутки, а не одна полоса прокрутки в каждом RecycleView.

Поэтому я просто поместил ScrollView в родительский контейнер, содержащий 2 RecycleViews, и использовал android:isScrollContainer="false" в RecycleView

<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutManager="LinearLayoutManager"
    android:isScrollContainer="false" />

Ответ 23

добавлять

android:descendantFocusability="blocksDescendants"

в вашем дочернем элементе SrollView или NestedScrollView (и родительский элемент ListView, recyclerview и gridview любой)

Ответ 24

Существует более простой способ отключить прокрутку (технически это скорее перехват события прокрутки и завершение его при выполнении условия), используя только стандартную функциональность. RecyclerView есть метод addOnScrollListener(OnScrollListener listener), и, используя только это, вы можете остановить прокрутку, просто так:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        if (viewModel.isItemSelected) {
            recyclerView.stopScroll();
        }
    }
});

Вариант использования: Допустим, вы хотите отключить прокрутку, когда вы нажимаете на один из элементов в RecyclerView чтобы вы могли выполнять с ним некоторые действия, не отвлекаясь на случайную прокрутку на другой элемент, и когда вы закончите с этим, просто нажмите на элементе снова, чтобы включить прокрутку. Для этого вам нужно присоединить OnClickListener к каждому элементу в RecyclerView, поэтому при нажатии на элемент он переключит isItemSelected с false на true. Таким образом, при попытке прокрутки RecyclerView автоматически вызовет метод onScrollStateChanged а поскольку для isItemSelected установлено значение true, он немедленно остановится, прежде чем RecyclerView получит возможность, ну... прокручивать.

Примечание: для удобства использования попробуйте использовать GestureListener вместо OnClickListener чтобы предотвратить accidental щелчки.

Ответ 25

Когда вы очищаете свой datalist, например, arrayList.clear(); ". после ясного datalist вы должны установить адаптер в recyclerView.. вот так..

'arrayList.clear();
AdapterforData adapterForNormalUserList = new  
AdapterforData(getActivity(),arrayList);
adapterForNormalUserList.notifyDataSetChanged();
recyclerView.setAdapter(adapterForNormalUserList);
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 1));'