androidmaterial-designshadowandroid-elevation

Android "elevation" not showing a shadow


I have a ListView, and with each list item I want it to show a shadow beneath it. I am using Android Lollipop's new elevation feature to set a Z on the View that I want to cast a shadow, and am already doing this effectively with the ActionBar (technically a Toolbar in Lollipop). I am using Lollipop's elevation, but for some reason it isn't showing a shadow under the list items. Here is how each list item's layout is set up:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    style="@style/block"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="@color/lightgray"
    >

    <RelativeLayout
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_marginLeft="40dp"
        android:layout_marginRight="40dp"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:elevation="30dp"
        >

        <ImageView
            android:id="@+id/documentImageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop" />

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/alphared"
            android:layout_alignParentBottom="true" >

            <appuccino.simplyscan.Extra.CustomTextView
                android:id="@+id/documentName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                app:typeface="light"
                android:paddingLeft="16dp"
                android:paddingTop="8dp"
                android:paddingBottom="4dp"
                android:singleLine="true"
                android:text="New Document"
                android:textSize="27sp"/>

            <appuccino.simplyscan.Extra.CustomTextView
                android:id="@+id/documentPageCount"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                app:typeface="italic"
                android:paddingLeft="16dp"
                android:layout_marginBottom="16dp"
                android:text="1 page"
                android:textSize="20sp"/>

        </LinearLayout>

    </RelativeLayout>

</RelativeLayout>

However, here is how it shows the list item, without a shadow: enter image description here

I have also tried the following to no avail:

  1. Set the elevation to the ImageView and TextViews themselves instead of the parent layout.
  2. Applied a background to the ImageView.
  3. Used TranslationZ in place of Elevation.

Solution

  • I've been playing around with shadows on Lollipop for a bit and this is what I've found:

    1. It appears that a parent ViewGroup's bounds cutoff the shadow of its children for some reason; and
    2. shadows set with android:elevation are cutoff by the View's bounds, not the bounds extended through the margin;
    3. the right way to get a child view to show shadow is to set padding on the parent and set android:clipToPadding="false" on that parent.

    Here's my suggestion to you based on what I know:

    1. Set your top-level RelativeLayout to have padding equal to the margins you've set on the relative layout that you want to show shadow;
    2. set android:clipToPadding="false" on the same RelativeLayout;
    3. Remove the margin from the RelativeLayout that also has elevation set;
    4. [EDIT] you may also need to set a non-transparent background color on the child layout that needs elevation.

    At the end of the day, your top-level relative layout should look like this:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        style="@style/block"
        android:gravity="center"
        android:layout_gravity="center"
        android:background="@color/lightgray"
        android:paddingLeft="40dp"
        android:paddingRight="40dp"
        android:paddingTop="20dp"
        android:paddingBottom="20dp"
        android:clipToPadding="false"
        >
    

    The interior relative layout should look like this:

    <RelativeLayout
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:background="[some non-transparent color]"
        android:elevation="30dp"
        >