[android] Add shadow to custom shape on Android

Is it possible to add a drop shadow to a custom shape in Android? After looking through the documentation, I only see a way to apply a text shadow.

I've tried this with no luck:

<?xml version="1.0" encoding="UTF-8"?> 
   <shape xmlns:android="http://schemas.android.com/apk/res/android" 
   android:shape="rectangle"> 
     <solid android:color="#90ffffff"/>
       <corners android:radius="12dp" />
     <item name="android:shadowColor">#000000</item> 
     <item name="android:shadowRadius">5</item> 
     <item name="android:shadowDy">3</item> 
   </shape>

This question is related to android android-layout

The answer is


For some reason shadows don't work if you set <solid> AND <stroke> on your custom background drawable. Creating a <layer-list> with separate layers for fill and borders fixes the issue:

<?xml version="1.0" encoding="utf-8"?>
<!-- Separate layers for solid and stroke, because no shadows get drawn otherwise (using elevation) -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/card_default" />
            <corners android:radius="@dimen/card_corner_radius" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <stroke android:color="@color/card_border" android:width="@dimen/card_border_width"/>
            <corners android:radius="@dimen/card_corner_radius" />
        </shape>
    </item>
</layer-list>

I would suggest a small improvement to Bruce's solution which is to prevent overdrawing the same shape on top of each other and to simply use stroke instead of solid. It would look like this:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Drop Shadow Stack -->
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <stroke android:color="#02000000" android:width="1dp"  />
            <corners android:radius="8dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <stroke android:color="#05000000" android:width="1dp" />
            <corners android:radius="7dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <stroke android:color="#10000000" android:width="1dp" />
            <corners android:radius="6dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <stroke android:color="#15000000" android:width="1dp" />
            <corners android:radius="5dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <stroke android:color="#20000000" android:width="1dp" />
            <corners android:radius="4dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <stroke android:color="#25000000" android:width="1dp" />
            <corners android:radius="3dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <stroke android:color="#30000000" android:width="1dp" />
            <corners android:radius="3dp" />
        </shape>
    </item>

    <!-- Background -->
    <item>
        <shape>
            <solid android:color="#FFF" />
            <corners android:radius="3dp" />
        </shape>
    </item>
</layer-list>

screenshot of the rendering of the shadow Lastly I wanted to point out for people who would like a shadow in a specific direction that all you have to do is set the top, bottom, left or right to 0dp (for a solid line) or -1dp (for nothing)


If you don't mind doing some custom drawing with the Canvas API, check out this answer about drop shadows. Here's a follow-up question to that one which fixes a problem in the original.


I think this method produces very good results:

<!-- Drop Shadow Stack -->
<item>
    <shape>
        <padding
                android:top="1dp"
                android:right="1dp"
                android:bottom="1dp"
                android:left="1dp"/>
        <solid android:color="#00CCCCCC"/>
    </shape>
</item>
<item>
    <shape>
        <padding
                android:top="1dp"
                android:right="1dp"
                android:bottom="1dp"
                android:left="1dp"/>
        <solid android:color="#10CCCCCC"/>
    </shape>
</item>
<item>
    <shape>
        <padding
                android:top="1dp"
                android:right="1dp"
                android:bottom="1dp"
                android:left="1dp"/>
        <solid android:color="#20CCCCCC"/>
    </shape>
</item>
<item>
    <shape>
        <padding
                android:top="1dp"
                android:right="1dp"
                android:bottom="1dp"
                android:left="1dp"/>
        <solid android:color="#30CCCCCC"/>
    </shape>
</item>
<item>
    <shape>
        <padding
                android:top="1dp"
                android:right="1dp"
                android:bottom="1dp"
                android:left="1dp"/>
        <solid android:color="#50CCCCCC"/>
    </shape>
</item>

<item>

    <shape android:shape="rectangle">
        <stroke android:color="#CCC" android:width="1dp"/>
        <solid android:color="#FFF" />
        <corners android:radius="2dp" />

    </shape>

</item>

I think this drop shadow value is good for most cases:

<solid android:color="#20000000" />

enter image description here

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

        <solid android:color="@android:color/white" >
        </solid>

        <stroke
            android:width="1dp"
            android:color="@color/LightGrey" >
        </stroke>

        <padding
            android:bottom="5dp"
            android:left="2dp"
            android:right="2dp"
            android:top="5dp" >
        </padding>

        <corners
            android:bottomLeftRadius="20dp"
            android:bottomRightRadius="20dp"
            android:radius="12dp"
            android:topLeftRadius="20dp"
            android:topRightRadius="20dp" />

        <gradient
            android:angle="90"
            android:centerColor="@android:color/white"
            android:centerY="0.2"
            android:endColor="#99e0e0e0"
            android:startColor="@android:color/white"
            android:type="linear" />

    </shape>

This is my version of a drop shadow. I was going for a hazy shadow all around the shape and used this answer by Joakim Lundborg as my starting point. What I changed is to add corners to all the shadow items and to increase the radius of the corner for each subsequent shadow item. So here is the xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Drop Shadow Stack -->
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#02000000" />
            <corners android:radius="8dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#05000000" />
            <corners android:radius="7dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#10000000" />
            <corners android:radius="6dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#15000000" />
            <corners android:radius="5dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#20000000" />
            <corners android:radius="4dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#25000000" />
            <corners android:radius="3dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#30000000" />
            <corners android:radius="3dp" />
        </shape>
    </item>

    <!-- Background -->
    <item>
    <shape>
            <solid android:color="#0099CC" />
        <corners android:radius="3dp" />
    </shape>
   </item>
</layer-list>

Old question, but Elevation, available with Material Design now provides a shadow to any views.

<TextView
android:id="@+id/myview"
...
android:elevation="2dp"
android:background="@drawable/myrect" />

See the docs at https://developer.android.com/training/material/shadows-clipping.html


This question may be old, but for anybody in future that wants a simple way to achieve complex shadow effects check out my library here https://github.com/BluRe-CN/ComplexView

Using the library, you can change shadow colors, tweak edges and so much more. Here's an example to achieve what you seek for.

<com.blure.complexview.ComplexView
        android:layout_width="400dp"
        android:layout_height="600dp"
        app:radius="10dp"
        app:shadow="true"
        app:shadowSpread="2">

        <com.blure.complexview.ComplexView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:color="#fdfcfc"
            app:radius="10dp" />
    </com.blure.complexview.ComplexView>

To change the shadow color, use app:shadowColor="your color code".


After Lots of search finally I got this

enter image description here

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

<!-- Bottom 2dp Shadow -->
<item>
    <shape  android:shape="rectangle">

        <solid android:color="#d8d8d8" />
        <corners android:radius="7dp" />

    </shape>
</item>

<!-- White Top color -->
<item android:bottom="3px">

    <shape  android:shape="rectangle">

    <solid android:color="#FFFFFF" />
    <corners android:radius="7dp" />


    </shape>

</item>


</layer-list>

This is how I do it:

Android Native Button with Shadows

Code bellow for one button STATE:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <!-- "background shadow" -->
    <item>
        <shape android:shape="rectangle" >
            <solid android:color="#000000" />

            <corners android:radius="15dp" />
        </shape>
    </item>
    <!-- background color -->
    <item
        android:bottom="3px"
        android:left="3px"
        android:right="3px"
        android:top="3px">
        <shape android:shape="rectangle" >
            <solid android:color="#cc2b2b" />


            <corners android:radius="8dp" />
        </shape>
    </item>
    <!-- over left shadow -->
    <item>
        <shape android:shape="rectangle" >
            <gradient
                android:angle="180"
                android:centerColor="#00FF0000"
                android:centerX="0.9"
                android:endColor="#99000000"
                android:startColor="#00FF0000" />

            <corners android:radius="8dp" />
        </shape>
    </item>
    <!-- over right shadow -->
    <item>
        <shape android:shape="rectangle" >
            <gradient
                android:angle="360"
                android:centerColor="#00FF0000"
                android:centerX="0.9"
                android:endColor="#99000000"
                android:startColor="#00FF0000" />

            <corners android:radius="8dp" />
        </shape>
    </item>
    <!-- over top shadow -->
    <item>
        <shape android:shape="rectangle" >
            <gradient
                android:angle="-90"
                android:centerColor="#00FF0000"
                android:centerY="0.9"
                android:endColor="#00FF0000"
                android:startColor="#99000000"
                android:type="linear" />

            <corners android:radius="8dp" />
        </shape>
    </item>
    <!-- over bottom shadow -->
    <item>
        <shape android:shape="rectangle" >
            <gradient
                android:angle="90"
                android:centerColor="#00FF0000"
                android:centerY="0.9"
                android:endColor="#00FF0000"
                android:startColor="#99000000"
                android:type="linear" />

            <corners android:radius="8dp" />
        </shape>
    </item>
</layer-list>

Then you should have a selector with diferent versions of the button, something like:

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

    <item android:drawable="@drawable/ic_button_red_pressed" android:state_pressed="true"/> <!-- pressed -->
    <item android:drawable="@drawable/ic_button_red_selected" android:state_focused="true"/> <!-- focused -->
    <item android:drawable="@drawable/ic_button_red_selected" android:state_selected="true"/> <!-- selected -->
    <item android:drawable="@drawable/ic_button_red_default"/> <!-- default -->

</selector>

hope this can help you..good luck


9 patch to the rescue, nice shadow could be achieved easily especially with this awesome tool -

Android 9-patch shadow generator

PS: if project won't be able to compile you will need to move black lines in android studio editor a little bit


The following worked for me: Just save as custom_shape.xml.

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

    <!-- "shadow" -->
    <item>
        <shape android:shape="rectangle" >
           <solid android:color="#000000"/>
           <corners android:radius="12dp" />
        </shape>
    </item>


    <item android:bottom="3px">
        <shape android:shape="rectangle"> 
            <solid android:color="#90ffffff"/>
            <corners android:radius="12dp" />
         </shape>
    </item>

</layer-list>

if you need a straight line shadow (like in bottom of toolbar) you can also use gradient xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:type="linear"
        android:angle="-90"
        android:startColor="#19000000" <!-- black transparent -->
        android:endColor="#00000000" /> <!-- full transparent -->
</shape>

hope this help some one