RecyclerView滚动至顶部时BottomSheetDialogFragment意外收起的解决方法
解决方案
这个问题的核心是RecyclerView滚动到顶部后,触摸事件被透传给了BottomSheet的拖拽逻辑,导致BottomSheet被误触发关闭。以下是几种实用的修复方式:
方法一:拦截RecyclerView顶部下拉事件
给RecyclerView设置自定义触摸监听器,判断是否已滚动到顶部,若是则消费下拉手势的事件,阻止其传递给BottomSheet:
recycler_searched_dishes.setOnTouchListener { v, event -> val recyclerView = v as RecyclerView val layoutManager = recyclerView.layoutManager as LinearLayoutManager // 判断是否滚动到顶部(完全可见或第一个可见项为0) val isAtTop = layoutManager.findFirstCompletelyVisibleItemPosition() == 0 || layoutManager.findFirstVisibleItemPosition() == 0 if (isAtTop && event.action == MotionEvent.ACTION_MOVE && event.rawY > v.y) { // 已在顶部且下拉,消费事件 true } else { // 其他情况正常传递事件 recyclerView.onTouchEvent(event) } }
方法二:禁用BottomSheet的拖拽功能(按需使用)
如果你的BottomSheet不需要通过拖拽手势关闭,可以直接关闭BottomSheet的拖拽行为:
在BottomSheetDialogFragment的onViewCreated方法中添加代码:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) dialog?.let { dialog -> val bottomSheet = dialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) val behavior = BottomSheetBehavior.from(bottomSheet) behavior.isDraggable = false // 禁用拖拽关闭 } }
方法三:调整RecyclerView的嵌套滚动属性
给RecyclerView添加android:nestedScrollingEnabled="false",阻止其与BottomSheet的嵌套滚动冲突,但此方法可能影响其他嵌套滚动场景,需根据实际情况测试:
<androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_searched_dishes" ... android:nestedScrollingEnabled="false" />
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

