Android "elevation" not showing a shadow

AndroidMaterial DesignShadowAndroid Elevation

Android Problem Overview


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.

Android Solutions


Solution 1 - Android

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"
    >

Solution 2 - Android

If you have a view with no background this line will help you

android:outlineProvider="bounds"

By default shadow is determined by view's background, so if there is no background, there will be no shadow also.

Solution 3 - Android

Apparently, you cannot just set an elevation on a View and have it appear. You also need to specify a background.

The following lines added to my LinearLayout finally showed a shadow:

android:background="@android:color/white"
android:elevation="10dp"

Solution 4 - Android

one other thing that you should be aware of, shadows will not show if you have this line in the manifest:

android:hardwareAccelerated="false"

I tried all of the suggested stuff but it only worked for me when i removed the line, the reason i had the line was because my app works with a number of bitmap images and they were causing the app to crash.

Solution 5 - Android

If you have a view with no background this line will help you

android:outlineProvider="bounds"

If you have a view with background this line will help you

android:outlineProvider="paddedBounds"

Solution 6 - Android

If you are adding elevation to a button element, you need to add the following line:

android:stateListAnimator="@null"

See https://stackoverflow.com/questions/27080338/android-5-0-androidelevation-works-for-view-but-not-button

Solution 7 - Android

Ugh, just spent an hour trying to figure this out. In my case I had a background set, however it was set to a color. This is not enough, you need to have the background of the view set to a drawable.

e.g. This won't have a shadow:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="165dp"
    android:background="@color/ight_grey"
    android:elevation="20dp"
    android:orientation="vertical"
    />

but this will

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="165dp"
    android:background="@drawable/selector_grey"
    android:elevation="20dp"
    android:orientation="vertical"
    />

EDIT: Have also discovered that if you use a selector as a background, if you don't have the corner set then the shadow won't show up in the Preview window but it will show up on the device

e.g. This doesn't have a shadow in preview:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <stroke
                android:width="1dp"
                android:color="@color/grey"/>
        </shape>
    </item>
</selector>

but this does:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <corners android:radius="1dp" />
            <stroke
                android:width="1dp"
                android:color="@color/grey"/>
        </shape>
    </item>
</selector>

Solution 8 - Android

Adding background color helped me.

<CalendarView
    android:layout_width="match_parent"
    android:id="@+id/calendarView"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true"
    android:layout_height="wrap_content"
    android:elevation="5dp"
   
    android:background="@color/windowBackground"

    />

Solution 9 - Android

Adding to the accepted answer, there is one more reason due to which elevation may not work as expected if the Bluelight filter feature on the phone is ON.

I was facing this issue when the elevation appeared completely distorted and unbearable in my device. But the elevation was fine in the preview. Turning off the Bluelight filter on phone resolved the issue.

So even after setting

android:outlineProvider="bounds"

The elevation is not working properly, then you can try to tinker with phone's color settings.

Solution 10 - Android

Sometimes like background="@color/***" or background="#ff33**" not work, I replace background_color with drawable, then it works

Solution 11 - Android

If it still not showing elevation try

    android:hardwareAccelerated="true" 

this will definitely help you.

Solution 12 - Android

If you want to have transparent background and android:outlineProvider="bounds" doesn't work for you, you can create custom ViewOutlineProvider:

class TransparentOutlineProvider extends ViewOutlineProvider {

	@Override
	public void getOutline(View view, Outline outline) {
		ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
		Drawable background = view.getBackground();
		float outlineAlpha = background == null ? 0f : background.getAlpha()/255f;
		outline.setAlpha(outlineAlpha);
	}
}

And set this provider to your transparent view:

transparentView.setOutlineProvider(new TransparentOutlineProvider());

Sources: https://code.google.com/p/android/issues/detail?id=78248#c13

[EDIT] Documentation of Drawable.getAlpha() says that it is specific to how the Drawable threats the alpha. It is possible that it will always return 255. In this case you can provide the alpha manually:

class TransparentOutlineProvider extends ViewOutlineProvider {

	private float mAlpha;

	public TransparentOutlineProvider(float alpha) {
		mAlpha = alpha;
	}

	@Override
	public void getOutline(View view, Outline outline) {
		ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
		outline.setAlpha(mAlpha);
	}
}

If your view background is a StateListDrawable with default color #DDFF0000 that is with alpha DDx0/FFx0 == 0.86

transparentView.setOutlineProvider(new TransparentOutlineProvider(0.86f));

Solution 13 - Android

give some background color to layout worked for me like:

    android:background="@color/catskill_white"
    android:layout_height="?attr/actionBarSize"
    android:elevation="@dimen/dimen_5dp"

Solution 14 - Android

I had some luck with setting clipChildren="false" on the parent layout.

Solution 15 - Android

I spent some time working on it and finally realized that when the background is dark, shadow is not visible

Solution 16 - Android

Also check if You don't change alpha on that view. I am investigating issue when i change alpha on some views, with elevation. They simply loose elevation when alpha is changed and changed back to 1f.

Solution 17 - Android

For me setting elevation, background and margin worked like a charm.

android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:background="@drawable/card_view" //any drawable or color
android:elevation="4dp"

Solution 18 - Android

I believe your issue stems from the fact that you have applied the elevation element to a relative layout that fills its parent. Its parent clips all child views within its own drawing canvas (and is the view that handles the child's shadow). You can fix this by applying an elevation property to the topmost RelativeLayout in your view xml (the root tag).

Solution 19 - Android

In my case fonts were the problem.

  1. Without fontFamily I needed to set android:background to some value.

  2. with fontFamily I had to add android:outlineProvider="bounds" setting:

Solution 20 - Android

In my case, this was caused by a custom parent component setting the rendering layer type to "Software":

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Removing this line of did the trick. Or course you need to evaluate why this is there in the first place. In my case it was to support Honeycomb, which is well behind the current minimum SDK for my project.

Solution 21 - Android

Setting both clipChildren and clipToPadding on parent layout did the job for me

android:clipChildren="false"
android:clipToPadding="false"

Solution 22 - Android

Setting android:clipToPadding="false" in the top relative layout has solved the problem.

Solution 23 - Android

set background color to the layout or view

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAggieDevView Question on Stackoverflow
Solution 1 - AndroidJustin PollardView Answer on Stackoverflow
Solution 2 - AndroidDmitry RyadnenkoView Answer on Stackoverflow
Solution 3 - AndroidJohn SlavickView Answer on Stackoverflow
Solution 4 - AndroidnadaView Answer on Stackoverflow
Solution 5 - AndroidDeepak sharmaView Answer on Stackoverflow
Solution 6 - Androiduser8102108View Answer on Stackoverflow
Solution 7 - AndroidodiggityView Answer on Stackoverflow
Solution 8 - AndroidTim GlennView Answer on Stackoverflow
Solution 9 - AndroidHemang KumarView Answer on Stackoverflow
Solution 10 - Androidray liuView Answer on Stackoverflow
Solution 11 - AndroidRohit LalwaniView Answer on Stackoverflow
Solution 12 - AndroidwirdilView Answer on Stackoverflow
Solution 13 - Androidsudhakara k sView Answer on Stackoverflow
Solution 14 - AndroidKaviView Answer on Stackoverflow
Solution 15 - AndroidEfi GView Answer on Stackoverflow
Solution 16 - AndroidMilan JurkulakView Answer on Stackoverflow
Solution 17 - Androiduser10061998View Answer on Stackoverflow
Solution 18 - AndroidFluffyC4n'tView Answer on Stackoverflow
Solution 19 - AndroidsoshialView Answer on Stackoverflow
Solution 20 - AndroidErrricPView Answer on Stackoverflow
Solution 21 - AndroidMichaël RandriaView Answer on Stackoverflow
Solution 22 - AndroidrajkabburView Answer on Stackoverflow
Solution 23 - AndroidSagar KondhareView Answer on Stackoverflow