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

Posted

技术标签:

【中文标题】嵌套在 BottomSheet 中的 RecyclerView(水平)防止垂直滚动【英文标题】:RecyclerView (horizontal) nested in BottomSheet preventing vertical scrolling 【发布时间】:2017-10-07 20:15:39 【问题描述】:

我有一个 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 (问题可以通过 commit #f59a7031 重现)

只需展开第一个底页。

【问题讨论】:

【参考方案1】:

问题出在哪里?在FrameLayoutBottomSheet 放入 CoordinatorLayout 时完美运行。然后BottomSheet 可以通过CoordinatorLayout 将它的滚动状态传递给作为CoordinatorLayout 的直接子级的其他视图。

为什么RecyclerView 无法将滚动状态传递给BottomSheet?它不是CoordinatorLayout 的直系子代。但是有一种方法可以通过它们:必须考虑实现NestedScrollingParentNestedScrollingChildRecyclerView。答案是: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_
    android:layout_
    android:background="#fff"
    android:orientation="vertical"
    android:fillViewport="true">

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

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

还要注意android:fillViewport="true",否则,您的RecyclerView 不会占据整个高度。

但它仍然无法正常工作。为什么? RecyclerView 必须被告知将垂直滚动传递给父级。如何?答案是recyclerView.setNestedScrollingEnabled(false);,但更好的描述是here。

顺便说一句:MultiSheetView 是一个很棒的功能,也是一种非常有趣的移动用户体验设计方法。

【讨论】:

我怀疑FrameLayout 阻止滚动事件传播到CoordinatorLayout。我想我在某个时候接近了这个解决方案,但是在视口问题上遇到了麻烦。非常感谢。 如果层次结构是:NestedScrollView -> ConstraintLayout -> RecylerView,RecyclerView 滚动行为不正确...我可以向下滚动但不能向上滚动。尝试向上滚动时,Bottomsheet(在本例中为 NestedScrollView)折叠...有什么想法吗? 此方法导致RecyclerView 的高度等于wrap_content,这对于性能来说是可怕的,因为它会导致所有子级的ViewHolders 单独膨胀不重复使用 非常感谢,这个答案解决了我的问题。 这不会在回收视图中回收视图..

以上是关于嵌套在 BottomSheet 中的 RecyclerView(水平)防止垂直滚动的主要内容,如果未能解决你的问题,请参考以下文章

BottomSheet的用法

BottomSheet的用法

如何验证脚手架中包含的 bottomSheet 内的表单?

Flutter:主从布局中的自定义 Appbar、浮动操作按钮和 BottomSheet

Android Kotlin:null 不能转换为非 null 类型 com.android.app.ui.category.CategoryAdapter.ViewHolder 想要在 recycl

android BottomSheet 未扩展到最大高度