在 Android 中为 BottomAppBar 实施 app:hideOnScroll
Implementing app:hideOnScroll for BottomAppBar in Android
我有一个应用 Activity,许多片段模型,其中几个片段有一个 RecyclerView 来显示包含内容的卡片。我还从 Material Design 2.0 实现了 BottomAppBar,一切都很好,除非 AppBar 阻塞了 RecyclerView 中的最后一个 CardView。
在布局方面,我在 Fragment 中的 ConstraintLayout 中有一个 RecyclerView,它位于主要 activity 的 FrameLayout 中。
文档显示,要在 Scroll 上隐藏 BottomAppBar,we need to implement RecyclerView inside a NestedScrollView. There is one question here on SO where the answer has stated the same as well, but there seems to be no actual documentation or examples to demonstrate how this is to be done, except for this article on Medium,它直接使用 Activity 中的 NestedScrollView,持有 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>
Activity布局
<?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>
您不应该将 BottomAppBar
和 FloatingActionButton
放在单独的 CoordinatorLayout
中。放弃他们所在的 CoordinatorLayout
,FrameLayout
周围的 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">
<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 在滚动时隐藏得很好。如果我们的滚动内容是 RecyclerView
,我们就不需要使用 NestedScrollView
,因为 RecyclerView
实现了 NestedScrollingChild.
This interface should be implemented by View subclasses that wish to support dispatching nested scrolling operations to a cooperating parent ViewGroup.
我有一个应用 Activity,许多片段模型,其中几个片段有一个 RecyclerView 来显示包含内容的卡片。我还从 Material Design 2.0 实现了 BottomAppBar,一切都很好,除非 AppBar 阻塞了 RecyclerView 中的最后一个 CardView。
在布局方面,我在 Fragment 中的 ConstraintLayout 中有一个 RecyclerView,它位于主要 activity 的 FrameLayout 中。
文档显示,要在 Scroll 上隐藏 BottomAppBar,we need to implement RecyclerView inside a NestedScrollView. There is one question here on SO where the answer has stated the same as well, but there seems to be no actual documentation or examples to demonstrate how this is to be done, except for this article on Medium,它直接使用 Activity 中的 NestedScrollView,持有 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>
Activity布局
<?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>
您不应该将 BottomAppBar
和 FloatingActionButton
放在单独的 CoordinatorLayout
中。放弃他们所在的 CoordinatorLayout
,FrameLayout
周围的 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">
<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 在滚动时隐藏得很好。如果我们的滚动内容是 RecyclerView
,我们就不需要使用 NestedScrollView
,因为 RecyclerView
实现了 NestedScrollingChild.
This interface should be implemented by View subclasses that wish to support dispatching nested scrolling operations to a cooperating parent ViewGroup.