15

So I've been searching the web for a way to display a simple shadow for a layout, but there is no proper way to do that.
All I found was a workaround where you create a layout behind the one you want a shadow to be applied to, and then tweak it to be transparent and some other stuff.

Is there any other way to have a simple layout shadow without adding a whole new layout ?

Jonik
  • 80,077
  • 70
  • 264
  • 372
Mehdiway
  • 10,337
  • 8
  • 36
  • 68

3 Answers3

47

I've been able to come up with a solution to this problem, and that by adding a View below our famous layout, displaying a gradient from one color to another.
Usually, the First color would be some sort of dark grayish, and the Second one would be the color of the background (in my case, i'll be having a light gray background so it's not completely white).

Layout + View

The xml would go like this :

...
<LinearLayout
    android:id="@+id/headerLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@drawable/headerImage"
        android:orientation="vertical" />

    <View
        android:layout_width="fill_parent"
        android:layout_height="5dip"
        android:background="@drawable/drop_shadow" >
    </View>
</LinearLayout>
...

drop_shadow.xml :

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

I hope it'll help ;)

Mehdiway
  • 10,337
  • 8
  • 36
  • 68
7

You can use the android.support.v4.view.ViewCompat class which sets the elevation of a view using the static method setElevation. The class is a helper for accessing features in view introduced after API Level 4 in a backwards compatible fashion.

The base elevation is in pixels eg

View mFab = (View) findViewById(R.id.floating_button);
ViewCompat.setElevation(mFab, 12);
Ovokerie Ogbeta
  • 503
  • 7
  • 5
6

For lollipop and above you can use elevation.

For older versions:

Here is a lazy hack from: http://odedhb.blogspot.com/2013/05/android-layout-shadow-without-9-patch.html

(toast_frame does not work on KitKat, shadow was removed from toasts)

just use:

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

or:

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

as a background

examples:

<TextView
        android:layout_width="fill_parent"
        android:text="I am a simple textview with a shadow"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:padding="16dp"
        android:textColor="#fff"
        android:background="@android:drawable/toast_frame"
        />

and with different bg color:

<LinearLayout
        android:layout_height="64dp"
        android:layout_width="fill_parent"
        android:gravity="center"
        android:background="@android:drawable/toast_frame"
        android:padding="4dp"
        >
    <Button
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:text="Button shadow"
            android:background="#33b5e5"
            android:textSize="24sp"
            android:textStyle="bold"
            android:textColor="#fff"
            android:layout_gravity="center|bottom"
            />

</LinearLayout>
Oded Breiner
  • 28,523
  • 10
  • 105
  • 71
  • 1
    In this approach, if I want to add a shadow to a layout, then how do I use background="#123456" AS WELL AS drawable/toast frame for the same layout? I think its not possible to use the attribute twice. So how do I proceed? – pblead26 Jul 06 '14 at 16:06
  • Just wrap it with a LinearLayout like example 2. – Oded Breiner Jul 07 '14 at 22:40