如何禁用RecyclerView滚动?
我无法禁用RecyclerView滚动。 我试着调用rv.setEnabled(false)但我仍然可以滚动。 
我怎样才能禁用滚动?
你应该重写你的recycleview的layoutmanager。 这样只会禁用滚动function,而没有其他function。 您仍然可以处理点击或任何其他触摸事件。 例如:-
原版的:
  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”标志,您可以暂时启用/禁用回收视图的滚动function。
也:
简单覆盖您的现有实施禁用滚动,并允许点击。
  linearLayoutManager = new LinearLayoutManager(context) { @Override public boolean canScrollVertically() { return false; } }; 
真正的答案是
 recyclerView.setNestedScrollingEnabled(false); 
更多信息在文档中
 这有点hackish解决方法,但它的工作原理; 您可以启用/禁用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 
这适用于我:
  recyclerView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return true; } }); 
 扩展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); } } } }); } 
 另一个select是setLayoutFrozen ,但它带有一堆其他的副作用。 
 你也可以在xml中设置android:nestedScrollingEnabled="false" 
 <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"> 
我知道这已经有了一个可以接受的答案,但是这个解决scheme没有考虑到我遇到的一个用例。
我特别需要一个仍然可点击的标题项目,但禁用了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) { } }); 
 recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() { @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { // Stop only scrolling. return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING; } }); 
出于某种原因@Alejandro Gracia答案只有在几秒钟后才开始工作。 我发现了一个即时阻止RecyclerView的解决scheme:
 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) { } }); 
重写onTouchEvent()和onInterceptTouchEvent(),并返回false,如果你根本不需要OnItemTouchListener。 这不会禁用ViewHolders的OnClickListeners。
 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; } } 
创build扩展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 ... ... > ... ... </com.yourpackage.xyz.NonscrollRecylerview > 
我一直在这个问题上挣扎了一段时间,所以我想分享一下我的经验,对于layoutManager解决scheme来说很好,但是如果你想要reEnable滚动,回收站将回到顶部。
到目前为止最好的解决scheme(至less对我来说)是使用@ 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); 
以下是我如何使用数据绑定完成的:
  <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}"/> 
代替“真实”我使用了一个布尔variables根据条件改变,以便回收站视图之间切换被禁用和启用。
写了一个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()