20

I add the new material design actionbar from the new appcompat and I use the new toolbar widget. I set a custom background on the toolbar on xml but my problem is that the drop shadow from the actionbar is not displayed. Do you know how to do this?

Toolbar code

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/my_awesome_toolbar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="@drawable/ab_background_textured"
    app:theme="@style/MyTheme"
    app:popupTheme="@style/MyTheme.Popup"/>

MyTheme style

<style name="MyTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textColorPrimary">@color/abc_primary_text_material_dark</item>
    <item name="actionMenuTextColor">@color/abc_primary_text_material_dark</item>
    <item name="android:textColorSecondary">#ffff8800</item>
</style>

MyTheme.Popup style

<style name="MyTheme.Popup" parent="ThemeOverlay.AppCompat.Dark">
    <item name="android:textColor">#ffffff</item>
</style>

Update

Like @Justin Powell suggested I add the actionBarStyle on my theme but still there is no drop shadow.

MyTheme style(Updated)

<style name="MyTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textColorPrimary">@color/abc_primary_text_material_dark</item>
    <item name="actionMenuTextColor">@color/abc_primary_text_material_dark</item>
    <item name="android:textColorSecondary">#ffff8800</item>
    <item name="android:actionBarStyle">@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse</item>
</style>
user3907002
  • 375
  • 1
  • 4
  • 17
  • Possible duplicate of [How to show the shadow of the ActionBar&Toolbar of the support library on all Android versions?](http://stackoverflow.com/questions/27474766/how-to-show-the-shadow-of-the-actionbartoolbar-of-the-support-library-on-all-an) – rds Sep 21 '16 at 08:26

4 Answers4

34

I found the solution in the Google IO app to be acceptable for myself, but saw no blog or Stackoverflow post fully explaining it. What you can do is grab their Apache 2 licensed drawer shadow asset from https://github.com/google/iosched/blob/36d88985ff6813fa9035530cd426393720a6f7b4/android/src/main/res/drawable-xxhdpi/bottom_shadow.9.png and then in the layout of your Activity:

<RelativeLayout android:layout_width="match_parent"
                android:layout_height="match_parent">
    <include android:id="@+id/toolbar"
             layout="@layout/toolbar"/>

    <FrameLayout android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:layout_below="@id/toolbar"
                 android:foreground="@drawable/header_shadow">
    <!-- YOUR STUFF HERE -->
    </FrameLayout>
</RelativeLayout>

Whereas header shadow is

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="header_shadow" type="drawable">@drawable/bottom_shadow</item>
</resources>

for API levels <21. Just like https://github.com/google/iosched/blob/8c798c58e592b8a25111610e216c7f3ee74c3a42/android/src/main/res/values/refs.xml and https://github.com/google/iosched/blob/8c798c58e592b8a25111610e216c7f3ee74c3a42/android/src/main/res/values-v21/refs.xml.

And to be elaborate, here is toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:elevation="4dp"
        app:theme="@style/ToolbarTheme"
        app:popupTheme="@style/AppTheme"/>
Fabian Frank
  • 1,115
  • 13
  • 14
  • 4
    Oh this is so wonderfully horrible, but seems to be a reasonable approach. I am gonna try this. Thanks! – benhylau Feb 08 '15 at 22:37
  • Wouldn't you have two shadows on >= Lollipop? – Kurovsky Sep 19 '15 at 19:30
  • No, you don't end up with 2 shadows, because for 21 and above the header_shadow is null. See the refs.xml in values-v21. – Fabian Frank Sep 19 '15 at 23:50
  • @FabianFrank why u r using FrameLayout for just shadow can,t we just used normal View class – shakil.k Jun 30 '16 at 16:39
  • Doesn't worked for me. Shadow applied on all layout from top to bootom screen. It's suck. The same suck as a google support libraries. – Trancer Oct 17 '16 at 15:54
  • https://github.com/google/iosched/blob/master/android/src/main/res/drawable-xxhdpi/bottom_shadow.9.png doesn't exist anymore. help. – Dominik Mar 04 '19 at 15:51
  • @e-nature The files are no longer on the master branch of the Google IO app, but you can still get them by manually navigating to an older version of the source, for example: https://github.com/google/iosched/tree/8c798c58e592b8a25111610e216c7f3ee74c3a42/android/src/main/res. I've updated the links in the answer to reflect that. – Fabian Frank Mar 05 '19 at 18:29
30

For pre-5.0 layouts, you can add the shadow back to the content below the toolbar by adding foreground="?android:windowContentOverlay" to the content's FrameLayout.

For example:

<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
    android:minHeight="?attr/actionBarSize"
    app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />

<FrameLayout
    android:id="@+id/fragmentContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:foreground="?android:windowContentOverlay"
    />

</LinearLayout>
Billy
  • 1,374
  • 1
  • 17
  • 25
  • Did you known how Google obtained the shadow without setting this attribute on their "Google IO 2014" app? (https://github.com/google/iosched/blob/master/android/src/main/res/layout/activity_settings.xml) – Cassio Landim Nov 05 '14 at 22:44
  • 5
    This is the drawable that they used in another activity layout: https://github.com/google/iosched/blob/master/android/src/main/res/drawable-xxhdpi/bottom_shadow.9.png as foreground. – Cassio Landim Nov 05 '14 at 23:40
  • @Billy Unfortunately ?android:windowContentOverlay is lighter then the original shadow so it doesn't look the same. Any clue which system resource may be used to mimic the original look? – tomrozb Nov 13 '14 at 17:38
  • GMail seems to use a gradient shape drawn on top of the main window. So they use a FrameLayout putting the content first and then the shadow. Having a hard time finding the correct values for the gradient though but it works. You must then hide the shadow for API level >= 21 – Christer Nordvik Nov 14 '14 at 20:20
  • @ChristerNordvik could you post your code here or as an answer? I think it would be very useful. – tomrozb Dec 01 '14 at 13:48
  • @tomrozb Done! Hope it is useful or someone else can help improve it :-) – Christer Nordvik Dec 02 '14 at 08:33
  • Can you please help me with this? the theme I use is "Theme.AppCompat.Light.NoActionBar" , and I use "setSupportActionBar" on the toolbar. For pre-Lollipop, this solution works fine, but on Lollipop, I don't see any shadow... Setting the elevation also didn't do anything. – android developer Dec 17 '14 at 08:36
  • 2
    Source code for google way of implementing drop shadow: https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget/DrawShadowFrameLayout.java – Ashish Rawat Aug 03 '15 at 11:16
  • @Ashish Rawat How can I use this Google source code? – Itiel Maimon Jul 26 '16 at 22:50
12

This is how I display the shadow:

<!-- API level 21 and above then the elevation attribute is enough. For some reason it can't be set directly on the include so I wrap it in a FrameLayout -->
<FrameLayout
    android:id="@+id/topwrapper"
    android:background="@color/theme_primary"
    android:elevation="4dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <include layout="@layout/toolbar_actionbar" />
</FrameLayout>

<FrameLayout
    android:layout_below="@id/topwrapper"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!-- This topshadow is hidden in code for API level 21 and above -->
    <include layout="@layout/topshadow" />
</FrameLayout>

And then the topshadow layout looks like this (adjust the 5dp to get the shadow height you want):

<View xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="5dp"
    android:id="@+id/shadow_prelollipop"
    android:background="@drawable/background_shadow" />

background_shadow.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <gradient
        android:startColor="#02444444"
        android:endColor="#33111111"
        android:angle="90"></gradient>
</shape>

toolbar_actionbar.xml

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:myapp="http://schemas.android.com/apk/res-auto"
    myapp:theme="@style/ActionBarThemeOverlay"
    myapp:popupTheme="@style/ActionBarPopupThemeOverlay"
    android:id="@+id/toolbar_actionbar"
    android:background="@color/theme_primary"
    myapp:titleTextAppearance="@style/ActionBar.TitleText"
    myapp:contentInsetStart="?actionBarInsetStart"
    android:layout_width="match_parent"
    android:layout_height="?actionBarSize" />
tomrozb
  • 25,773
  • 31
  • 101
  • 122
Christer Nordvik
  • 2,518
  • 3
  • 35
  • 52
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>
    <item name="logo">@drawable/ab_logo</item>
    <item name="displayOptions">useLogo|showHome|showTitle|showCustom</item>
</style>

add to Basetheme

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