Реализация приложения: hideOnScroll для BottomAppBar в Android

У меня есть приложение с одной моделью Activity, много фрагментов, где несколько фрагментов имеют RecyclerView для отображения карточек с контентом. Я также реализовал BottomAppBar из Material Design 2.0, и все в порядке, кроме случаев, когда AppBar блокирует последний CardView в RecyclerView.

Что касается макета, у меня есть RecyclerView внутри ConstraintLayout внутри фрагмента, который находится в FrameLayout в основном действии.

В документации показано, что для скрытия BottomAppBar при прокрутке используется нам нужно реализовать RecyclerView внутри NestedScrollView. Существует один вопрос здесь на SO, где в ответе также указано то же самое, но, похоже, нет фактической документации или примеров, демонстрирующих, как это должно быть сделано, за исключением эта статья на Medium, который напрямую использует NestedScrollView в Activity, удерживая CoordinatorLayout, который содержит ConstraintLayout.

Примечание: я думаю, что это также работает по волшебству, потому что дублирование макета в моем фрагменте вообще не влияет на мое приложение.

Как мне здесь использовать NestedScrollView?

PS: Мне нужно иметь TextView, поскольку я установил RecyclerView на VISIBILITY.GONE и установил TextView на VISIBLE, когда у меня нет данных для отображения.

Макет фрагмента

<android.support.constraint.ConstraintLayout 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/constraintLayout"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    tools:context = "in.domain.APPNAME.Fragments.FragmentList">


    <android.support.v7.widget.RecyclerView
        android:id = "@+id/recyclerViewIncident"
        android:layout_width = "fill_parent"
        android:layout_height = "fill_parent"
        android:paddingBottom = "30dp"
        android:visibility = "visible"
        app:layout_constraintBottom_toBottomOf = "parent"
        app:layout_constraintEnd_toEndOf = "parent"
        app:layout_constraintHorizontal_bias = "0.0"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toTopOf = "parent"
        app:layout_constraintVertical_bias = "0.0" />

    <TextView
        android:id = "@+id/emptyView"
        android:layout_width = "wrap_content"
        android:layout_height = "17dp"
        android:layout_marginBottom = "8dp"
        android:layout_marginEnd = "8dp"
        android:layout_marginStart = "8dp"
        android:layout_marginTop = "8dp"
        android:text = "No Incidents to display"
        android:visibility = "visible"
        app:layout_constraintBottom_toBottomOf = "parent"
        app:layout_constraintEnd_toEndOf = "parent"
        app:layout_constraintHorizontal_bias = "0.503"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toTopOf = "parent" />

</android.support.constraint.ConstraintLayout>

Схема занятий

<?xml version = "1.0" encoding = "utf-8"?>
<android.support.design.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:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:id = "@+id/uberLayout"
    tools:context = ".APPNAME">

    <android.support.constraint.ConstraintLayout
        android:layout_width = "match_parent"
        android:layout_height = "match_parent">

        <FrameLayout
            android:id = "@+id/containerFrameLayout"
            android:layout_width = "match_parent"
            android:layout_height = "match_parent">

        </FrameLayout>

    </android.support.constraint.ConstraintLayout>

    <android.support.design.widget.CoordinatorLayout
        android:layout_width = "match_parent"
        android:layout_height = "match_parent">


        <android.support.design.bottomappbar.BottomAppBar
            android:id = "@+id/bottom_app_bar"
            style = "@style/Widget.MaterialComponents.BottomAppBar"
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content"
            android:layout_gravity = "bottom"
            app:backgroundTint = "@color/colorPrimary"
            app:fabAlignmentMode = "center"
            app:navigationIcon = "@drawable/baseline_menu_white_24dp"
            app:hideOnScroll = "true"
            app:popupTheme = "@style/ThemeOverlay.AppCompat.Light"
            app:theme = "@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        </android.support.design.bottomappbar.BottomAppBar>

        <android.support.design.widget.FloatingActionButton
            android:id = "@+id/floatingActionButton"
            android:layout_width = "100dp"
            android:layout_height = "wrap_content"
            android:clickable = "true"
            android:src = "@drawable/baseline_add_white_24dp"
            app:backgroundTint = "@color/brightred"
            app:fabSize = "normal"
            app:layout_anchor = "@+id/bottom_app_bar"
            tools:layout_editor_absoluteX = "160dp"
            tools:layout_editor_absoluteY = "465dp" />


    </android.support.design.widget.CoordinatorLayout>

</android.support.design.widget.CoordinatorLayout>
3
0
1 285
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не должны помещать BottomAppBar и FloatingActionButton в отдельный CoordinatorLayout. Откажитесь от CoordinatorLayout, в котором они находятся, от ConstraintLayout вокруг вашего FrameLayout, и это уже может решить проблему.

<?xml version = "1.0" encoding = "utf-8"?>
<android.support.design.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:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:id = "@+id/uberLayout"
    tools:context = ".APPNAME">

    <FrameLayout
        android:id = "@+id/containerFrameLayout"
        android:layout_width = "match_parent"
        android:layout_height = "match_parent">
    </FrameLayout>

    <android.support.design.bottomappbar.BottomAppBar
        android:id = "@+id/bottom_app_bar"
        style = "@style/Widget.MaterialComponents.BottomAppBar"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:layout_gravity = "bottom"
        app:backgroundTint = "@color/colorPrimary"
        app:fabAlignmentMode = "center"
        app:navigationIcon = "@drawable/baseline_menu_white_24dp"
        app:hideOnScroll = "true"
        app:popupTheme = "@style/ThemeOverlay.AppCompat.Light"
        app:theme = "@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

    <android.support.design.widget.FloatingActionButton
        android:id = "@+id/floatingActionButton"
        android:layout_width = "100dp"
        android:layout_height = "wrap_content"
        android:src = "@drawable/baseline_add_white_24dp"
        app:backgroundTint = "@color/brightred"
        app:fabSize = "normal"
        app:layout_anchor = "@+id/bottom_app_bar" />

</android.support.design.widget.CoordinatorLayout>

Я использую похожий макет, с той лишь разницей, что <fragment> вместо <FrameLayout>, а BottomAppBar отлично скрывается при прокрутке. Нам не нужно использовать NestedScrollView, если наш прокручиваемый контент в любом случае является RecyclerView, потому что RecyclerView реализует NestedScrollingChild.

This interface should be implemented by View subclasses that wish to support dispatching nested scrolling operations to a cooperating parent ViewGroup.

Другие вопросы по теме