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

我如何禁用滚动?


当前回答

写了一个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()

其他回答

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

我在这个问题上纠结了好几个小时, 所以我想分享一下我的经验, 对于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);

由于setLayoutFrozen已弃用,你可以通过使用suppressLayout冻结你的RecyclerView来禁用滚动。

冻结:

recyclerView.suppressLayout(true)

解冻:

recyclerView.suppressLayout(false)

你只需添加这一行:

recyclerView.suppressLayout(true)

在activity的onCreate方法中,你可以简单地做:

recyclerView.stopScroll()

然后停止滚动。