我不能在RecyclerView中禁用滚动。我尝试调用rv.setEnabled(false),但我仍然可以滚动。

我如何禁用滚动?


当前回答

遇到了包含多个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" />

其他回答

创建继承RecyclerView类的类

public class NonScrollRecyclerView extends RecyclerView {

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

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

    public NonScrollRecyclerView(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.NonScrollRecyclerView 
     ...
     ... 
  />

2022年5月

在新版本的android和api中进行了多次尝试后,这种方法对我来说很有效。

Kotlin的新答案

创建一个名为ScrollDisabledRecyclerView的类,并放入如下代码:

class ScrollDisabledRecyclerView : RecyclerView { constructor(context: Context?) : super(context!!) constructor(context: Context?, @Nullable attrs: AttributeSet?) : super(context!!, attrs) constructor(context: Context?, @Nullable attrs: AttributeSet?, defStyle: Int) : super( context!!, attrs, defStyle ) override fun onTouchEvent(e: MotionEvent): Boolean { return e.action == MotionEvent.ACTION_MOVE } override fun onInterceptTouchEvent(e: MotionEvent): Boolean { return false } }

在你的XML中使用这个类而不是RecyclerView(这个类是从它扩展来的):

<info.sanaebadi.ScrollDisabledRecyclerView android:id="@+id/recyclerView" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" android:clipToPadding="true" tools:listitem="@layout/multiple_questions_row" />

最后,使用mainactivity中的按钮处理next和previous,如下所示:

注意:我正在使用视图绑定

binding.buttonNextQuestion.setOnClickListener {
            val totalItemCount: Int = binding.recyclerView.adapter!!.itemCount
            if (totalItemCount <= 0) return@setOnClickListener
            val lastVisibleItemIndex: Int = linearLayoutManager.findLastVisibleItemPosition()
            if (lastVisibleItemIndex >= totalItemCount) return@setOnClickListener
            linearLayoutManager.smoothScrollToPosition(
                binding.recyclerView,
                null,
                lastVisibleItemIndex + 1
            )

        }
        binding.buttonPreviousQuestion.setOnClickListener {
            val firstVisibleItemIndex: Int =
                linearLayoutManager.findFirstCompletelyVisibleItemPosition()
            if (firstVisibleItemIndex > 0) {
                linearLayoutManager.smoothScrollToPosition(
                    binding.recyclerView,
                    null,
                    firstVisibleItemIndex - 1
                )
            }
        }
recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
            // Stop only scrolling.
            return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING;
        }
    });

这是一个有点笨拙的方法,但它是有效的;你可以在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 

另一个替代方案是setLayoutFrozen,但它带来了一堆其他副作用。

https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html setLayoutFrozen(布尔)