RecyclerView(水平)嵌套在 BottomSheet 中防止垂直滚动

RecyclerView (horizontal) nested in BottomSheet preventing vertical scrolling

我有一个 RecyclerView 使用 LinearLayoutManagerHORIZONTAL 方向,嵌套在 FrameLayout 使用 BottomSheet Behavior.

尝试在 RecyclerView 上垂直拖动时,BottomSheet 不响应拖动事件。大概这是因为水平方向的 LayoutManager 禁用了垂直滚动。

我试过覆盖 LinearLayoutManager.canScrollVertically() 并返回 true。这种 有效。如果您以非常小心的方式垂直拖动,BottomSheet 将会响应。但是,一旦涉及任何水平移动,BottomSheet 就会停止响应垂直拖动事件。

我不确定覆盖 canScrollVertically() 是否是正确的方法 - 从用户体验的角度来看肯定感觉不对。

我还注意到,如果我使用 ViewPager 而不是水平方向 LayoutManagerRecyclerViewBottomSheet 会响应垂直滑动事件想要。

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

这里有一个问题示例:

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

只需展开第一个底部sheet。

问题出在哪里?在FrameLayoutBottomSheet 放在 CoordinatorLayout 中时效果很好。然后 BottomSheet 可以通过 CoordinatorLayout 将它的滚动状态传递给作为 CoordinatorLayout 的直接子视图的其他视图。

为什么 RecyclerView 无法将滚动状态传递给 BottomSheet?它不是 CoordinatorLayout 的直接子代。但是有一种方法可以传递它们: RecyclerView 必须放在实现 NestedScrollingParent and NestedScrollingChild. The answer to that is: 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 是一项很棒的功能,也是一种非常有趣的移动用户体验设计方法。