29

I want to achieve something like that. (not the FAB or the Snackbar). How can i create a layout, overlaying the AppBarLayout? Like this! (For Example)

AppBarLayout with overlaying content

Like Play Store:

Just like on the Play Store

My AppBarLayout with CoordinatorLayout and NestedScrollView with RelativeLayout as content looks like this:

<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:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="@dimen/_118sdp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsingToolbarLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:contentScrim="@color/mpc_pink"
        app:expandedTitleMarginStart="@dimen/_40sdp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <de.mypostcardstore.widgets.ItemImageView
            android:id="@+id/header"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@color/mpc_pink"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.7" />

        <android.support.v7.widget.Toolbar
            android:id="@+id/article_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:minHeight="?attr/actionBarSize"
            app:contentScrim="@color/mpc_pink"
            app:layout_collapseMode="pin"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />


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

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

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:colorBackground"
    android:fillViewport="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <RelativeLayout
        android:layout_width="match_parent".....>

It would be awesome if someone could help me out. I can not find anything on the internet...

Thanks in advance!

jarlh
  • 42,561
  • 8
  • 45
  • 63
X7S
  • 409
  • 1
  • 4
  • 10
  • 1
    What is the real question? Do you want a Card over an extended toolbar? – Gabriele Mariotti Jun 24 '15 at 16:28
  • 1
    Also what do you want to happen when you scroll? From your code, it looks like you want your `AppBarLayout` to scroll entirely off the screen when you scroll - is that correct? – ianhanniballake Jun 24 '15 at 16:49
  • Pretty much like the Tablet Design of the App-Page on Google Play.http://imgur.com/7C30E7P – X7S Jun 24 '15 at 16:49
  • Not used the support library and the particular widgets you are using but have you tried setting positive padding to the scrollview and then use clipToPadding? – Sahil Dave Jun 27 '15 at 17:12

4 Answers4

48

Just add something like

app:behavior_overlapTop="64dp"

to your NestedScrollView and it will be placed above the expanded toolbar.

In addition, you should add something like

app:expandedTitleMarginBottom="70dp"

to your CollapsingToolbarLayout so the title does not appear under your overlaid scroll content.

Ander Webbs
  • 1,158
  • 1
  • 8
  • 11
  • 1
    This works for me too, But in my case i have viewpager instade of nested scrollview and i dont want that collapsing toolbar to scroll and collapse. but cant find solution. Tried overriding some method to disable drag, but it will move view pager below collapsing toolbar. – P Vartak Nov 15 '18 at 12:36
  • @PVartak any luck finding the solution for your issue? – hushed_voice Oct 16 '19 at 05:41
  • @free_style nope. At last, I kept less area on which the user can click. Actual scroll issue never solved. – P Vartak Oct 16 '19 at 09:25
15

It's quite simple, really. You could achieve that by using a combination of ToolBar, FrameLayout, and your content view (could be a ListView like your first example, or anything).

The idea is to make your FrameLayout possess the same color as your ToolBar, giving the illusion of ToolBar being much larger than it is. Then all that is left to do is to make your content view be the last (or in API 21 and above: possess the highest elevation attribute) so that it would appear as if it floats above the aforementioned FrameLayout.

See my illustration below:

enter image description here

Now that you got the big idea, below is some real live XML snippet for doing such thing. (I actually use this layout in one of my apps) :

<!-- Somewhere in your layout.xml -->

....

    <android.support.v7.widget.Toolbar
        android:id="@+id/tb_toolbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/abc_action_bar_default_height_material"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        app:contentInsetStart="72dp"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

    <!-- This is the 'faux' ToolBar I've been telling you about. This is the part that will be overlaid by the content view below. -->
    <FrameLayout
        android:id="@+id/v_toolbar_extension"
        android:layout_width="match_parent"
        android:layout_height="64dp"
        android:layout_below="@+id/tb_toolbar"
        android:background="?attr/colorPrimary"
        android:elevation="2dp"/>

    <!-- Normally, I use this FrameLayout as a base for inflating my fragments. You could just use put your content view here. -->
    <FrameLayout
        android:id="@+id/ly_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/tb_toolbar"
        android:elevation="3dp"/>

....

Note that my ly_content has higher elevation value than that of v_toolbar_extension. This is what will give you that desired 'overlaid toolbar' effect.

Last but not least, you would want to add this line somewhere in your activity's onCreate() :

/* Assuming mToolbar exists as a reference to your ToolBar in XML. */
setSupportActionBar(mTbToolbar);
getSupportActionBar().setElevation(0);

What that codes woud do is to set your ToolBar elevation to zero; removing preset shadows that were given as a default to ToolBars. If you don't do this, said shadow will create a "seam" between your ToolBar and your FrameLayout, thus breaking the illusion of those two being the same.

p.s., It is also important to give your content view a padding on each side. Doing so, your content view will not cover the entire width of the screen (which would render this effect useless).


Note: I see some good answers here that mentioned the absence of FrameLayout and instead making the ToolBar taller. While in theory it might work as well as my proposed solution, you might have problems when trying to manipulate scrolling; by doing that, you won't be able to separate ToolBar and its extension. You'll be forced to either make the Toolbar static or scroll all of the ToolBar altogether (makes scrolling a bit weird).

Add to that, the fact that you can't easily assign a custom drawable into a Toolbar. Hence makes it hard to follow the Google Play example you've given above. While if you're using my solution, all you'd need to do is just make your Toolbar transparent and assign the drawable to the FrameLayout instead.

Hadi Satrio
  • 4,272
  • 2
  • 24
  • 45
  • How would you get this to work for pre-Lollipop devices? setElevation() won't work. – adao7000 Jul 02 '15 at 18:46
  • On pre-L, those shadows weren't set by `setElevation()` but by modifying your `style.xml`. Refer to here for how: http://stackoverflow.com/q/12246388/1727589 – Hadi Satrio Jul 02 '15 at 21:55
  • that won't look good as the toolbar will have a shadow beneath and when the toolbar collapses you will see the division between the toolbar and the framelayout that has a background color – ponnex Feb 20 '16 at 19:07
  • 1
    No need to do that hack. Using `app:behavior_overlapTop` attribute can achieve that very easily, even on Older APIs (as per support lib). – sud007 Jul 06 '16 at 07:11
  • saved my a** today. `app:behavior_overlapTop` does not work when we disable the scroll flag – hushed_voice Oct 16 '19 at 10:35
1

I had a similar requirement and I achieved it as below.

Your activity theme should extend Theme.AppCompat.Light.NoActionBar. I created a Layout XML File as:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar_main"
    android:layout_width="match_parent"
    android:layout_height="@dimen/action_bar_size_x2"
    android:background="@color/colorPrimary"
    android:minHeight="?attr/actionBarSize" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="15dp"
    android:layout_marginRight="15dp"
    android:layout_marginTop="@dimen/action_bar_size"
    android:orientation="vertical" >

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:text="@string/app_name"
                android:textSize="24sp" />
        </LinearLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

And the Activity should be something like this:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar maintoolbar = (Toolbar) findViewById(R.id.toolbar_main);
        setSupportActionBar(maintoolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }
}

I got a view like this : enter image description here

Akanksha Hegde
  • 1,738
  • 11
  • 14
0

I did try to implement effects like you referred which is called Card Toolbar in Android, and it did work as expected. Here is my layout, Take a look at it:

<FrameLayout 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:background="@color/background_material_light" >
<android.support.v7.widget.Toolbar
    android:layout_width="match_parent"
    android:layout_height="@dimen/toolbar_double_height"
    android:background="?attr/colorPrimary" />
<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="@dimen/cardview_toolbar_spacer"
    android:layout_marginRight="@dimen/cardview_toolbar_spacer"
    android:layout_marginTop="?attr/actionBarSize"
    app:cardBackgroundColor="@android:color/white">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <android.support.v7.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize" />
        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:alpha="0.12"
            android:background="@android:color/black" />
    </LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>

Hope you'll be inspired.

SilentKnight
  • 13,761
  • 19
  • 49
  • 78