Add views below toolbar in CoordinatorLayout
I have the following layout:
<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>
I add Fragment
s into the FrameLayout
, replacing them. One of my Fragment
s is a list, which has the following layout:
<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"/>
My problem here that the toolbar is drawn over the list. I tried to solve that by wrapping the content of the CoordinatorLayout
into a LinearLayout
, that solved the overdraw, but that way the appbar scrolling behavior no longer work.
Any help is much appreciated!
Solution 1:
Take the attribute
app:layout_behavior="@string/appbar_scrolling_view_behavior"
off the RecyclerView
and put it on the FrameLayout
that you are trying to show under the Toolbar
.
I've found that one important thing the scrolling view behavior does is to layout the component below the toolbar. Because the FrameLayout
has a descendant that will scroll (RecyclerView
), the CoordinatorLayout
will get those scrolling events for moving the Toolbar
.
One other thing to be aware of: That layout behavior will cause the FrameLayout
height to be sized as if the Toolbar
is already scrolled, and with the Toolbar
fully displayed the entire view is simply pushed down so that the bottom of the view is below the bottom of the CoordinatorLayout
.
This was a surprise to me. I was expecting the view to be dynamically resized as the toolbar is scrolled up and down. So if you have a scrolling component with a fixed component at the bottom of your view, you won't see that bottom component until you have fully scrolled the Toolbar
.
So when I wanted to anchor a button at the bottom of the UI, I worked around this by putting the button at the bottom of the CoordinatorLayout
(android:layout_gravity="bottom"
) and adding a bottom margin equal to the button's height to the view beneath the toolbar.
Solution 2:
I managed to fix this by adding:
android:layout_marginTop="?android:attr/actionBarSize"
to the FrameLayout like so:
<FrameLayout
android:id="@+id/content"
android:layout_marginTop="?android:attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
Solution 3:
As of Android studio 3.4, You need to put this line in your Layout which holds the RecyclerView
.
app:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior"
Solution 4:
To use collapsing top ToolBar or using ScrollFlags of your own choice we can do this way:From Material Design get rid of 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>