android - AppBarLayout 阻止 RecyclerView 在 BottomSheet 中滚动

标签 android android-recyclerview bottom-sheet android-appbarlayout appbar

我制作了一个简单的布局,其中有一个 AppBarLayout(不滚动)、中间的一些内容和一个 BottomSheet。这个 BottomSheet 实际上是一个带有 BottomSheetBehavior 的 LinearLayout,里面有一个 RecyclerView。

这个 BottomSheet 在展开时将 RecyclerView 放置在 AppBarLayout 的顶部。问题在于,当用户尝试滚动此 RecyclerView 时,下面的 AppBarLayout 窃取了滚动。

我要留下布局代码,但我上传了整个 example project使用 GIF 到 GitHub 进行说明。

布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinator_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:liftOnScroll="false">

        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:title="@string/app_name" />

        <androidx.appcompat.widget.AppCompatTextView
            android:layout_width="match_parent"
            android:layout_height="56dp"
            android:background="?colorSurface"
            android:gravity="center_vertical"
            android:padding="16dp"
            android:text="Subtitle"
            android:textAppearance="?textAppearanceSubtitle1" />

        <androidx.appcompat.widget.AppCompatTextView
            android:layout_width="match_parent"
            android:layout_height="56dp"
            android:background="?colorSurface"
            android:gravity="center_vertical"
            android:padding="16dp"
            android:text="Subsubtitle"
            android:textAppearance="?textAppearanceBody2" />

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="56dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <androidx.appcompat.widget.AppCompatTextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp"
            android:text="@string/lorem_ipsum"
            android:textAppearance="?textAppearanceBody1" />

    </androidx.core.widget.NestedScrollView>

    <LinearLayout
        android:id="@+id/bottom_sheet_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="bottom"
        android:background="#FFF"
        android:elevation="5dp"
        android:orientation="vertical"
        app:behavior_hideable="false"
        app:behavior_peekHeight="64dp"
        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/bottom_sheet_header"
            android:layout_width="match_parent"
            android:layout_height="64dp"
            android:gravity="center_vertical"
            android:padding="16dp"
            android:text="Fruits"
            android:textAppearance="?textAppearanceHeadline6" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

我试过:

  • nestedScrollingEnabled 属性放在不同的地方,但没有用,这种行为发生在旧的 API(如 JellyBean)中;
  • 在我看到这个的原始项目中,如果目标 View 是 BottomSheet 的 RecyclerView,我写了一个自定义的 AppBarLayout 行为来忽略,但也没有工作;
  • 设置整个 AppBarLayout GONE 当 BottomSheet 展开并且足够有趣时 AppBarLayout 的行为就像我设置为 INVISIBLE (如果以编程方式设置为 GONE,它的行为就像不可见的,如果在膨胀之前设置,它的行为符合预期)。

由于项目规范,我避免使用 Fragment 来创建此 BottomSheet。

最佳答案

我所做的解决方法是将 CoordinatorLayout 一分为二,其中一个包含 AppBarLayout 和 NestedScrollView,另一个包含 BottomSheet (LinearLayout)。

层次结构,以问题的布局为例,最终是这样的:

<FrameLayout>
    <CoordinatorLayout>
        <AppBarLayout>
            <MaterialToolbar/>
            <AppCompatTextView/>
            <AppCompatTextView/>
        </AppBarLayout>
        <NestedScrollView>
            <AppCompatTextView/>
        </NestedScrollView>
    </CoordinatorLayout>

    <CoordinatorLayout>
        <LinearLayout>
            <AppCompatTextView/>
            <RecyclerView/>
        </LinearLayout>
    </CoordinatorLayout>
</FrameLayout>

在我的例子中,这是可行的,因为我的 BottomSheet 不需要与其他 View 协调任何行为。

关于android - AppBarLayout 阻止 RecyclerView 在 BottomSheet 中滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64011422/

相关文章:

android - 最初展开的 BottomSheetDialog 不起作用

android - 平滑地设置 BottomSheet 窥视高度的动画

android - Android 中的 ListView 滚动滞后

android - FFmpeg 无法为 android 构建

java - 在回收器 View 中的嵌套回收器 View 内的嵌套列表中添加项目

java - ArrayList<String> 使用改造 android 解析为 recyclerview

Android 持久 Bottom Sheet 初始可见性

java - Android Espresso 执行点击第一个匹配项

android使用左右滑动更改图像

android - 滚动向 TextView 添加值