How do add shadow above a view in android

If you need to have shadow just on one side of the view (e.g. on top), you can add another View before it and use gradient shadow for its background.

Here is the gradient file top_shadow_gradient.xml that you have to store in drawable folder:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient android:startColor="#40000000" android:endColor="#30ffffff" android:angle="90"/>
</shape>

And here is a sample layout how to use it:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent"
    android:orientation="vertical">

    <View
        android:layout_width="match_parent"
        android:layout_height="8dp"
        android:background="@drawable/top_shadow_gradient" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:orientation="vertical"
        android:paddingTop="8dp">

        <!-- Put your content here-->

    </LinearLayout>

</LinearLayout>

Important: The root layout have to be transparent (android:background="@android:color/transparent") and your "content" layout need to have white background (android:background="#ffffff").

And this is the result: enter image description here


Here are some solutions for this problem - choose your best:

  • On StackOverFlow, in post from 22th October 2012, How to show shadow around the linearlayout in android?, you would read:

There is no such attribute in Android, to show a shadow. But possible ways to do it are:

  1. Add a plain LinearLayout with grey color, over which add your actual layout, with margin at bottom and right equal to 1 or 2 dp

  2. Have a 9-patch image with a shadow and set it as the background to your Linear layout

and

There is also another solution to the problem by implementing a layer-list that will act as the background for the LinearLayoout.

Add background_with_shadow.xml file to res/drawable. Containing:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item >
        <shape 
            android:shape="rectangle">
        <solid android:color="@android:color/darker_gray" />
        <corners android:radius="5dp"/>
        </shape>
    </item>
    <item android:right="1dp" android:left="1dp" android:bottom="2dp">
        <shape 
            android:shape="rectangle">
        <solid android:color="@android:color/white"/>
        <corners android:radius="5dp"/>
        </shape>
    </item>
</layer-list>

Then add the the layer-list as background in your LinearLayout.

<LinearLayout
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:background="@drawable/background_with_shadow"/>

You can also read: http://odedhb.blogspot.com/2013/05/android-layout-shadow-without-9-patch.html

  • Another post from StackOverflow, how to set shadow to a View in android?, gives you another solution (using two views that form the shadow.):
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" 
    android:padding="10dp"
    android:background="#CC55CC">
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TableLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:stretchColumns="0">
            <TableRow>
                <LinearLayout
                    android:id="@+id/content"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content">
                    <TextView  
                        android:layout_width="fill_parent" 
                        android:layout_height="wrap_content"
                        android:background="#FFFFFF" 
                        android:text="@string/hello" />
                </LinearLayout>
                <View
                    android:layout_width="5dp"
                    android:layout_height="fill_parent"
                    android:layout_marginTop="5dp"
                    android:background="#55000000"/>
            </TableRow>
        </TableLayout>
        <View
            android:layout_width="fill_parent"
            android:layout_height="5dp"
            android:layout_marginLeft="5dp"
            android:background="#55000000"/>
    </LinearLayout>
</FrameLayout>
  • You can also use specific drawable form Android resources to mimic shadow effect. Look at: thttps://stackoverflow.com/questions/21211870/android-view-shadow or just read a post below:

I'm using Android Studio 0.8.6 and I couldn't find:

android:background="@drawable/abc_menu_dropdown_panel_holo_light"

so I found this instead:

android:background="@android:drawable/dialog_holo_light_frame"

and it looks like this:

![enter image description here][1]

[1]: http://i.stack.imgur.com/tId9L.jpg


If you're insteresting in clean Material Design effect, read some documentation like below:

  • Android L Developer Preview: Views and Shadows
  • Defining Shadows and Clipping Views

On hack I found for this is to wrap your view in a parent and use rotate. E.g. if you have a cardview and are adding elevation to it, you can put two rotates like this to achieve a shadow above instead of below:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clipToPadding="false"
    android:paddingBottom="10dp"
    android:rotation="180">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:rotation="180"
        app:cardElevation="8dp">
    <!--Card view content-->
    </android.support.v7.widget.CardView>
</RelativeLayout>

This gives something like the attached screenshot.

enter image description here

There's still a problem with this - this requires the paddingBottom to be set on the parent layout which means it'll be obvious that any scrollable sibling above the layout isn't going below it.

So even in today's age of elevation and outline provider, it's better to add a translucent view instead. :(