RecyclerView(水平方向)嵌套在BottomSheet中,导致无法垂直滚动。

25

我有一个使用LinearLayoutManagerHORIZONTAL方向的RecyclerView,嵌套在使用BottomSheet BehaviorFrameLayout中。

当尝试在RecyclerView上垂直拖动时,BottomSheet不响应拖动事件。可能是因为对于水平方向的LayoutManager,禁用了垂直滚动。

我尝试重写LinearLayoutManager.canScrollVertically()并返回true。这种方法“有点”有效...如果您以非常小心的方式垂直拖动,则BottomSheet将会响应。但是,只要涉及任何水平移动,BottomSheet就停止响应垂直拖动事件。

我不确定在这里覆盖canScrollVertically()是否是正确的方法-从用户体验的角度来看,它肯定不太合适。

我还注意到,如果我使用具有水平方向LayoutManagerViewPager而不是RecyclerView,则BottomSheet会按预期响应垂直滑动事件。

是否有其他LayoutManagerRecyclerViewBottomSheet Behavior或其他方法可以帮助将垂直滚动事件传播到BottomSheet Behavior

这里有一个问题的示例:

https://github.com/timusus/bottomsheet-test (使用提交#f59a7031可以重现问题)

只需展开第一个底部工作表。

2个回答

41
问题出在哪儿呢?在FrameLayout中。当将BottomSheet放在CoordinatorLayout中时,BottomSheet可以完美地通过CoordinatorLayout将其滚动状态传递给其他作为CoordinatorLayout直接子项的视图。
为什么RecyclerView不能将滚动状态传递给BottomSheet呢?因为它不是CoordinatorLayout的直接子项。但是存在一种方法可以将它们传递:必须将RecyclerView放在实现NestedScrollingParentNestedScrollingChild的视图中。答案是:NestedScrollView 所以你的fragment_sheetX.xml布局应该像这样:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    android:orientation="vertical"
    android:fillViewport="true">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</android.support.v4.widget.NestedScrollView>

请注意 android:fillViewport="true",否则您的 RecyclerView 将无法占据整个高度。

然而,它仍然不起作用。为什么?必须告诉 RecyclerView 将垂直滚动传递给父项。如何做到这一点?答案是 recyclerView.setNestedScrollingEnabled(false);,但最好在这里进行描述。

顺便说一下:MultiSheetView 是一个很棒的功能,也是移动 UX 设计的一种非常有趣的方法。


我怀疑FrameLayout阻止滚动事件传播到CoordinatorLayout。我认为我曾经接近解决方案,但在视口问题上遇到了麻烦。非常感谢。 - Tim Malseed
1
如果层次结构是:NestedScrollView -> ConstraintLayout -> RecylerView,则RecyclerView滚动不正确...我可以向下滚动,但无法向上滚动。尝试向上滚动时,Bottomsheet(在这种情况下为NestedScrollView)会折叠...有什么想法吗? - skm
16
这种方法会使RecyclerView的高度等同于wrap_content,这对性能非常糟糕,因为它会导致为所有子项逐个膨胀ViewHolder而没有重用。 - Josh
非常感谢,这个答案解决了我的问题。 - Fereshteh Naji
这将不会在 RecyclerView 中重复使用视图。 - Rohit
@skm,你找到答案了吗?如何使RecylerView在BottomSheet中双向滚动?我在我的项目中也遇到了同样的问题。 - d.u.a.l

0
android:nestedScrollingEnabled="false"

在RecyclerView中设置此项即可解决问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接