179

I'm updating my app with the new Toolbar from the support library v21. My problem is that the toolbar does not cast any shadow if I don't set the "elevation" attribute. Is that the normal behavior or I'm doing something wrong?

My code is:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical">

   <android.support.v7.widget.Toolbar
       xmlns:app="http://schemas.android.com/apk/res-auto"
       android:id="@+id/my_awesome_toolbar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:background="?attr/colorPrimary"
       android:elevation="4dp"
       android:minHeight="?attr/actionBarSize"
       app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
       app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

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

And in my Activity - OnCreate method:

    Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
    setSupportActionBar(toolbar);
MrBrightside
  • 2,669
  • 3
  • 17
  • 24
  • Are you seeing this on a device running Lollipop? – rlay3 Oct 27 '14 at 05:13
  • 3
    On a device running Lollipop shows the shadow because of the elevation attribute but not on KitKat or older versions. Thats the expected behavior for the elevation attribute as documentation says, but I was expecting that, by default without the elevation attribute, the shadow would cast like it does the Action Bar on every version. – MrBrightside Oct 27 '14 at 10:36
  • I posted a possible solution here: http://stackoverflow.com/a/26759202/553905 – Billy Nov 05 '14 at 14:09
  • Use /values folders and styles.xml to apply the proper shadow code based on OS version (see below). – radley Apr 02 '15 at 23:32

21 Answers21

262

I ended up setting my own drop shadow for the toolbar, thought it might helpful for anyone looking for it:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="top"
              android:orientation="vertical">

    <android.support.v7.widget.Toolbar android:id="@+id/toolbar"
                                       android:layout_width="match_parent"
                                       android:layout_height="wrap_content"
                                       android:background="@color/color_alizarin"
                                       android:titleTextAppearance="@color/White"
                                       app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

    <FrameLayout android:layout_width="match_parent"
                 android:layout_height="match_parent">

        <!-- **** Place Your Content Here **** -->

        <View android:layout_width="match_parent"
              android:layout_height="5dp"
              android:background="@drawable/toolbar_dropshadow"/>

    </FrameLayout>

</LinearLayout>

@drawable/toolbar_dropshadow:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
       android:shape="rectangle">

    <gradient android:startColor="@android:color/transparent"
              android:endColor="#88333333"
              android:angle="90"/>

</shape>

@color/color_alizarin

<color name="color_alizarin">#e74c3c</color>

enter image description here

Airon Tark
  • 8,900
  • 4
  • 23
  • 19
I'm a frog dragon
  • 7,865
  • 7
  • 46
  • 49
  • 3
    Don't forget to hide your view if the device you are running is >= to Lollipop, if not you'll end up with two shadows. – mradzinski Feb 01 '15 at 00:29
  • Excellent solution! I was struggling trying to achieve a consistent look for the toolbar between Lollipop and previous versions. Now it's perfect. – fehbari Feb 04 '15 at 15:38
  • @dragon who spits fire it worked, but View is below every content in xml but when i run it is on top, i'm curious why – Jemshit Mar 07 '15 at 10:21
  • 1
    This is the wrong way to to it because you'll have to remove that view for 5.0 layouts. Use android:windowContentOverlay or android:foreground instead. – radley Apr 03 '15 at 16:59
  • 3
    From Google about designing the [Toolbar material design](http://www.google.com/design/spec/what-is-material/objects-in-3d-space.html#objects-in-3d-space-elevation-android-), you should set `android:layout_height="4dp"` for the height of shadow, instead of `5dp`. Actually, elevation is the same as the height of shadow you set on `FrameLayout`. – Anggrayudi H May 03 '15 at 11:07
  • 2
    I'm having trouble with this solution because I inflate my activities layout into the frame layout in your example, can you think of a way for this to work? – Zach Sperske Jul 03 '15 at 02:21
  • 2
    Recommending using "android:endColor="#c7c7c7" over android:endColor="#88333333" – Mohammad Faisal Apr 13 '16 at 07:33
  • @ZachSperske use relative layout instead like this: http://stackoverflow.com/a/30171360/5223160 – jzeferino Sep 30 '16 at 16:14
  • i think you updated your answer without removing @color/color_alizarin – usernotnull Mar 16 '17 at 15:21
  • @MohammadFaisal that's a lot better on Note 8 since the alternative has a black line at the top. Would this work on non white backgrounds though? seems too light – behelit Jan 18 '18 at 05:23
  • 1
    I recommend using a black shadow instead of gray: `android:startColor="@android:color/transparent"` and `android:endColor="#32000000"` – Mr-IDE Mar 06 '19 at 14:15
  • Please remember that gradient is not shadow. – Pedro Paulo Amorim Jun 16 '20 at 13:28
223

Google released the Design Support library a few weeks ago and there is a nifty solution for this problem in this library.

Add the Design Support library as a dependency in build.gradle :

compile 'com.android.support:design:22.2.0'

Add AppBarLayout supplied by the library as a wrapper around your Toolbar layout to generate a drop shadow.

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
       <android.support.v7.widget.Toolbar
           .../>
    </android.support.design.widget.AppBarLayout>

Here is the result :

enter image description here

There are lots of other tricks with the design support library.

  1. http://inthecheesefactory.com/blog/android-design-support-library-codelab/en
  2. http://android-developers.blogspot.in/2015/05/android-design-support-library.html

AndroidX

As above but with dependency:

implementation 'com.google.android.material:material:1.0.0'

and com.google.android.material.appbar.AppBarLayout

weston
  • 54,145
  • 21
  • 145
  • 203
Binoy Babu
  • 16,699
  • 17
  • 91
  • 134
  • 32
    Setting the `AppBarLayout` as a wrapper around the `Toolbar` doesn't set any shadow for me. Note that I don't use a navigation drawer. Any ideas on why it doesn't work? – avb Jun 29 '15 at 11:45
  • @avb1994 Can't say for sure, I have tested it without a nav drawer. Can you post it as a question with the layout file? – Binoy Babu Jun 29 '15 at 11:56
  • see my question: https://stackoverflow.com/questions/31115531/add-elevation-shadow-on-toolbar-for-pre-lollipop-devices thanks for your comment – avb Jun 29 '15 at 12:19
  • 2
    You don't need this two lines compile 'com.android.support:support-v4:22.2.0' compile 'com.android.support:appcompat-v7:22.2.0', because compile 'com.android.support:design:22.2.0' depends on them – Andrew Jul 02 '15 at 02:49
  • 9
    Do note this only works for lollipop and above. It won't work pre lollipop since underneath it's just using ViewCompat.setElevation(). – Amirul Zin Jul 04 '15 at 05:39
  • As far as I know, with the design lib you can simply set elevation now. – JacksOnF1re Oct 14 '15 at 16:02
  • Questions says "Toolbar", not "AppBarLayout" – vortal Jan 03 '19 at 17:24
  • @vortal `Toolbar` is placed inside `AppBarLayout`, take a look one more time – user155 Mar 24 '19 at 18:52
  • @avb unfortunately it works for Android 21 and higher only – user155 Mar 24 '19 at 19:19
  • Also note, that depending on your layout, you may also need to add `android:clipChildren="false"`, to your parent(s) of `AppBarLayout`, otherwise shadow can get cut out – Peter Aug 27 '20 at 11:30
28

You can't use the elevation attribute before API 21 (Android Lollipop). You can however add the shadow programmatically, for example using a custom view placed below the Toolbar.

@layout/toolbar

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/blue"
    android:minHeight="?attr/actionBarSize"
    app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />

<View
    android:id="@+id/toolbar_shadow"
    android:layout_width="match_parent"
    android:layout_height="3dp"
    android:background="@drawable/toolbar_dropshadow" />

@drawable/toolbar_dropshadow

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <gradient
        android:startColor="@android:color/transparent"
        android:endColor="#88333333"
        android:angle="90"/> </shape>

in your activity layout <include layout="@layout/toolbar" />

enter image description here

Muhammad Aamir Ali
  • 20,419
  • 10
  • 66
  • 57
19

Use /values folders to apply the correct shadow style based on OS version.

For under 5.0 devices, use /values/styles.xml to add windowContentOverlay to the body of your activity:

<style name="MyViewArea">
    <item name="android:foreground">?android:windowContentOverlay</item>
</style>

<style name="MyToolbar">
    <item name="android:background">?attr/colorPrimary</item>
</style>

Then add your own custom shadow by changing your Theme to include:

<item name="android:windowContentOverlay">@drawable/bottom_shadow</item>

You can grab Google's IO app shadow resource here: https://github.com/google/iosched/blob/master/android/src/main/res/drawable-xxhdpi/bottom_shadow.9.png

For 5.0 devices & later, use /values-v21/styles.xml to add elevation to your toolbar using a custom header style:

<style name="MyViewArea">
</style>

<style name="MyToolbar">
    <item name="android:background">?attr/colorPrimary</item>
    <item name="android:elevation">4dp</item>
</style>

Note that in the second case, I had to create an empty MyViewArea style so the windowContentOverlay wouldn't show up too.

[Update: changed resource names and added Google shadow.]

Jeff Lockhart
  • 5,379
  • 4
  • 36
  • 51
radley
  • 3,212
  • 1
  • 22
  • 18
  • May I know what is MyBody and MyHeader? Where I should apply them? – Cheok Yan Cheng May 16 '15 at 20:50
  • I updated the names: MyHeader is now MyToolbar and MyBody is MyViewArea. You can assign styles in xml layouts like this: style="@style/MyToolbar". – radley May 17 '15 at 02:20
  • What is MyViewArea applied to? – Zach Sperske Jul 01 '15 at 22:41
  • Your page / body / view area. – radley Jul 02 '15 at 00:28
  • I think `android:foreground` only works on FrameLayout before API 23. – androidguy Jan 12 '17 at 04:16
  • Thanks!...I forgot what I did before to have the shadow and this post reminded me!....its android:background attribute of the toolbar ppl!! Also I had set the app:elevation (my min sdk was 21) and thus was wondering why it wasn't working, since my toolbar was inflated programmatically, I forgot that the underlying container which encompasses my toolbar and rest of the view had a background...not sure if it was transparent which might have caused the isssue. – mahee96 Feb 05 '21 at 16:45
14

If you are seting the ToolBar as ActionBar then just call:

getSupportActionBar().setElevation(YOUR_ELEVATION);

Note: This must be called after setSupportActionBar(toolbar);

Roberto B.
  • 3,065
  • 2
  • 18
  • 11
14

This worked for me very well:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/primary"
    card_view:cardElevation="4dp"
    card_view:cardCornerRadius="0dp">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/primary"
        android:minHeight="?attr/actionBarSize" />

</android.support.v7.widget.CardView>
Islam A. Hassan
  • 1,357
  • 15
  • 20
  • How can this work if on pre lollipop cardview pads itself in order to draw the shadow? This is what I get: http://i.imgur.com/BIj8env.png this answer worked for me and it doesn't suffer from the drawbacks from this one: http://stackoverflow.com/questions/26575197/no-shadow-by-default-on-toolbar/30171360#30171360 – Aspiring Dev Jan 26 '17 at 15:58
  • 2
    Actually, you're better off with the AppBarLayout as in this answer http://stackoverflow.com/a/31026359/1451716 My answer is old, before the AppBarLayout was released – Islam A. Hassan Feb 08 '17 at 15:26
  • 1
    Is this even legal? It's not supposed to be used with Toolbar. OMG! – user155 Mar 24 '19 at 20:47
9

i added

<android.support.v7.widget.Toolbar
...
android:translationZ="5dp"/>

in toolbar description and it works for me. Using 5.0+

Alex Mazur
  • 99
  • 1
  • 1
7

My problem is that the toolbar does not cast any shadow if I don't set the "elevation" attribute. Is that the normal behavior or I'm doing something wrong?

That's the normal behavior. Also see the FAQ at the end of this post.

cygery
  • 2,309
  • 3
  • 18
  • 25
7

Was toying with this for hours, here's what worked for me.

Remove all the elevation attributes from the appBarLayout and Toolbar widgets (including styles.xml if you are applying any styling).

Now inside activity,apply the elvation on your actionBar:

Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setElevation(3.0f);

This should work.

Irshu
  • 8,248
  • 8
  • 53
  • 65
  • What if I want the elevation on the AppBarLayout, as it can collapse/expand ? – android developer Dec 26 '17 at 11:02
  • 1
    `setElevation` takes a parameter as pixels. You have to convert it appropriately, e.g. `(int) (3.0 / Resources.getSystem().getDisplayMetrics().density)` – Ely Jul 08 '18 at 06:17
6

All you need is a android:margin_bottom equal to the android:elevation value. No AppBarLayout, clipToPadding, etc. required.

Example:

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:layout_marginBottom="4dp"
    android:background="@android:color/white"
    android:elevation="4dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!--Inner layout goes here-->

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.appcompat.widget.Toolbar>
Rohan Taneja
  • 9,687
  • 3
  • 36
  • 48
4

You can also make it work with RelativeLayout. This reduces layout nesting a little bit ;)

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

    <include
        android:id="@+id/toolbar"
        layout="@layout/toolbar" />

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/toolbar" />

    <View
        android:layout_width="match_parent"
        android:layout_height="5dp"
        android:layout_below="@id/toolbar"
        android:background="@drawable/toolbar_shadow" />
</RelativeLayout>
Aspiring Dev
  • 505
  • 1
  • 4
  • 17
iluu
  • 406
  • 3
  • 13
3

You need to use background color and elevation togather.

<com.google.android.material.appbar.MaterialToolbar
     app:elevation="8dp"
     android:elevation="8dp"
     android:background="@color/white"/>
Rasoul Miri
  • 11,234
  • 1
  • 68
  • 78
2

In my situation elevation doesn't work well because I haven't given any background to the toolbar. Try giving background color to the toolbar then set elevation and it will work well.

Hellsid
  • 21
  • 1
2
<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="4dp"
    android:elevation="4dp">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:buttonGravity="center_vertical" />
</androidx.cardview.widget.CardView>
1

Most solutions work fine here. Would like to show another, similar alternative :

gradle:

implementation 'androidx.appcompat:appcompat:1.0.0-rc02'
implementation 'com.google.android.material:material:1.0.0-rc02'
implementation 'androidx.core:core-ktx:1.0.0-rc02'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

You layout can have a Toolbar View, and a shadow for it, below, similar to this (need modification of course) :

<LinearLayout
    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:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:titleTextAppearance="@style/Base.TextAppearance.Widget.AppCompat.Toolbar.Title"/>

    <include
        layout="@layout/toolbar_action_bar_shadow"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

res/drawable-v21/toolbar_action_bar_shadow.xml

<androidx.appcompat.widget.AppCompatImageView
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="wrap_content" android:src="@drawable/msl__action_bar_shadow"/>

res/drawable/toolbar_action_bar_shadow.xml

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent" android:layout_height="wrap_content"
    android:foreground="?android:windowContentOverlay" tools:ignore="UnusedAttribute"/>

res/drawable/msl__action_bar_shadow.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <shape
            android:dither="true"
            android:shape="rectangle" >
            <gradient
                android:angle="270"
                android:endColor="#00000000"
                android:startColor="#33000000" />

            <size android:height="10dp" />
        </shape>
    </item>

</layer-list>

styles.xml

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources>

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar as Toolbar)
    }
}

Full sample here, as I've noticed the IDE has a bug of saying foreground attribute is too new to be used here.

android developer
  • 114,585
  • 152
  • 739
  • 1,270
1

The correct answer will be to add
android:backgroundTint="#ff00ff" to the tool bar with android:background="@android:color/white"

If you use other color then white for the background it will remove the shadow. Nice one Google!

user3193413
  • 575
  • 7
  • 10
0

actionbar_background.xml

    <item>
        <shape>
            <solid android:color="@color/black" />
            <corners android:radius="2dp" />
            <gradient
                android:startColor="@color/black"
                android:centerColor="@color/black"
                android:endColor="@color/white"
                android:angle="270" />
        </shape>
    </item>

    <item android:bottom="3dp" >
        <shape>

            <solid android:color="#ffffff" />
            <corners android:radius="1dp" />
        </shape>
    </item>
</layer-list>

add to actionbar_style background

<style name="Theme.ActionBar" parent="style/Widget.AppCompat.Light.ActionBar.Solid">
    <item name="background">@drawable/actionbar_background</item>
    <item name="android:elevation">0dp</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:layout_marginBottom">5dp</item>

name="displayOptions">useLogo|showHome|showTitle|showCustom

add to Basetheme

<style name="BaseTheme" parent="Theme.AppCompat.Light">
   <item name="android:homeAsUpIndicator">@drawable/home_back</item>
   <item name="actionBarStyle">@style/Theme.ActionBar</item>
</style>
Samet ÖZTOPRAK
  • 3,112
  • 3
  • 32
  • 33
0

For 5.0 + : You can use AppBarLayout with Toolbar. AppBarLayout has "elevation" attribure.

 <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:elevation="4dp"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <include layout="@layout/toolbar" />
    </android.support.design.widget.AppBarLayout>
Eugene Lezov
  • 722
  • 7
  • 12
0

I had similar problem with the shadow. The shadow is drawn by direct parent of AppBarLayout in my case. If height of the parent is the same as AppBarLayout's the shadow cannot be drawn. So checking size of the parent layout and maybe layout remake can solve the problem. https://www.reddit.com/r/androiddev/comments/6xddb0/having_a_toolbar_as_a_fragment_the_shadow/

Radiofisik
  • 150
  • 11
0

I am posting this because this took me hours to find so i hope it may help someone.

I had a problem that the shadow/elevation was not showing though i created a simple activity and placed the toolbar as follows:

 <androidx.appcompat.widget.Toolbar
        android:id="@+id/mt_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:layout_collapseMode="pin"
        android:background="@color/colorPrimaryDark"
        android:elevation="12dp"/>

It turns out that in the manifest setting android:hardwareAccelerated="false" was causing it! once i removed it, the shadow appeared

Rashad.Z
  • 2,494
  • 2
  • 27
  • 58
0
Just put  background
 <androidx.appcompat.widget.Toolbar
                android:layout_width="match_parent"
                android:elevation="8dp"
                android:background="#fff"

                android:layout_height="?android:attr/actionBarSize"></androidx.appcompat.widget.Toolbar>