在CoordinatorLayout中工具栏下添加视图

189

我有以下的布局:

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/main_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

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

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</android.support.design.widget.CoordinatorLayout>

我将 Fragment 添加到 FrameLayout 中,替换它们。其中一个 Fragment 是一个列表,其布局如下:

<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
我的问题是工具栏覆盖了列表。 我试图通过将CoordinatorLayout的内容包装到LinearLayout中来解决这个问题,这解决了重叠的问题,但是这种方式下应用栏的滚动行为不再起作用。
非常感谢任何帮助!
4个回答

386

获取属性

app:layout_behavior="@string/appbar_scrolling_view_behavior"

RecyclerView 从原位置移出,放在你想要显示在 Toolbar 下方的 FrameLayout 上。

我发现滚动视图行为的一个重要作用是布局工具栏下面的组件。因为 FrameLayout 拥有一个会滚动的子元素 (RecyclerView),所以 CoordinatorLayout 将获得这些滚动事件来移动 Toolbar


还有一件事需要注意:这种布局行为会导致 FrameLayout 的高度被调整为 好像 Toolbar 已经滚动了,当 Toolbar 完全显示时,整个视图会被推到下面,使得视图底部低于 CoordinatorLayout 底部。

这让我很意外。我希望视图在工具栏上下滚动时能够动态调整大小。因此,如果你有一个带有固定组件的滚动组件,并且该组件位于视图底部,你将无法看到该底部组件,直到你完全滚动 Toolbar

因此,当我想要锚定一个按钮在 UI 底部时,我通过将按钮放在 CoordinatorLayout 的底部 (android:layout_gravity="bottom"),并将视图下方的底部边距添加到按钮的高度。


1
非常感谢,这真的很有效!但是我的唯一问题是,如果工具栏被移出后,用另一个Fragment替换包含列表的Fragment后,它不会返回。我设法手动显示了工具栏,方法在这里 - WonderCsabo
哇,我一直以为Fragment自己的布局完全取代了FrameLayout的“占位符”,但我发现这根本不是这样。谢谢你的答案!它帮助了我很多。 - Aspiring Dev
@Surendar D,请检查一下这个链接,如果您可以的话:https://dev59.com/MaDia4cB1Zd3GeqPAkHt - Mohamed Rihan
好的。谢谢! - Razvan
如果您想在没有滚动事件的情况下以编程方式展开/折叠应用栏,则视图的布局与滚动行为耦合是一个问题。 - Louis

95

我通过添加以下内容解决了这个问题:

android:layout_marginTop="?android:attr/actionBarSize"

将其添加到FrameLayout中,如下所示:

 <FrameLayout
        android:id="@+id/content"
        android:layout_marginTop="?android:attr/actionBarSize"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
       />

11
不要添加marginTop,而是添加app:layout_behavior="@string/appbar_scrolling_view_behavior"。 - Naveed Ahmad
4
当@string/appbar_scrolling_view_behavior不可用时,完美解决方案。 - Julius
1
请使用android:layout_marginTop="?android:attr/actionBarSize" - Martin Pfeffer
9
这种做法有些取巧,增加一个可能大小的边距(假设您始终会有该大小的工具栏)会在某个时候出现问题。 - Kenny
如果您使用CollapsingToolbarLayout,高度将不会是恒定的,这样肯定会出现问题。 - Louis

3

要使用可折叠式顶部工具栏或自己选择的滚动标志,我们可以这样做:从Material Design中获取并去掉FrameLayout。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.coordinatorlayout.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleGravity="top"
            app:layout_scrollFlags="scroll|enterAlways">


        <androidx.appcompat.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin">

            <ImageView
                android:id="@+id/ic_back"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_arrow_back" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="back"
                android:textSize="16sp"
                android:textStyle="bold" />

        </androidx.appcompat.widget.Toolbar>


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

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/post_details_recycler"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:padding="5dp"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            />

</androidx.coordinatorlayout.widget.CoordinatorLayout>


2
从Android Studio 3.4开始,您需要在包含RecyclerView的布局中添加此行代码。"最初的回答"
app:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接