我不能在RecyclerView中禁用滚动。我尝试调用rv.setEnabled(false),但我仍然可以滚动。
我如何禁用滚动?
我不能在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()
然后停止滚动。