26

I am trying to make use of the elevation property in the latest Android Lollipop preview release. I set the targetSdk to 21 and the theme to Material. Next i added a background shape to a TextView and set the elevation to 8dp but the TextView is not showing any signs of a shadow. That is on a Nexus7 running the Lollipop preview. Is there anything else i have to consider?

Here is the layout:

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

  <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:background="@drawable/rect"
      android:text="hallo world"
      android:padding="8dp"
      android:elevation="8dp" />

</LinearLayout>

This is the background drawable:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle">
    <solid android:color="#7d0073ff" />
    <corners android:radius="16dp" />
</shape>

Here is the TextView:

Android elevation

Moritz
  • 9,453
  • 7
  • 45
  • 57

9 Answers9

59

For some reason if you set a solid color with a transparency, the elevation shadow does not show up.

In your example, I changed #7d0073ff to #0073ff and I got a shadow.

This is probably a bug, as in their documentation it gives a similar example using a translucent background color.

rlay3
  • 8,052
  • 6
  • 27
  • 21
18

After going through the docs again, I finally found the solution.

Just add card_view:cardUseCompatPadding="true" to your CardView and shadows will appear on Lollipop devices.

What happens is, the content area in a CardView take different sizes on pre-lollipop and lollipop devices. So in lollipop devices the shadow is actually covered by the card so its not visible. By adding this attribute the content area remains the same across all devices and the shadow becomes visible.

My xml code is like :

<android.support.v7.widget.CardView
    android:id="@+id/media_card_view"
    android:layout_width="match_parent"
    android:layout_height="130dp"
    card_view:cardBackgroundColor="@android:color/white"
    card_view:cardElevation="2sp"
    card_view:cardUseCompatPadding="true"
    >
...
</android.support.v7.widget.CardView>
Ram Patra
  • 14,608
  • 12
  • 60
  • 69
17

ADDING android:elevation shadow to an ImageView:

android:clipToPadding="false"
+
android:outlineProvider="bounds"
+
android:elevation="2dp"
Informatheus
  • 975
  • 1
  • 7
  • 19
9

I was also having this problem, and as it turns out, you need to turn hardware acceleration on in the android manifest

<application
  ...
  android:hardwareAccelerated="true">
vcapra1
  • 1,852
  • 3
  • 24
  • 37
  • 1
    if you tried card_view:cardUseCompatPadding="true" and it didn't work, this is your answer – Klaasel Sep 29 '15 at 11:52
  • @vcapra1: by adding android:hardwareAccelerated="true", app is crash. Not any of solutions are worked :( – UrMi Jan 29 '16 at 06:08
4

be aware, if you have the following line in the manifest then shadows wont show:

android:hardwareAccelerated="false"

nada
  • 1,319
  • 9
  • 17
3

TL;DR

Check your card: (or whatever word you use) namespace declaration and make sure it matches this: xmlns:card="http://schemas.android.com/apk/res-auto"

I know there are a few answers here already, but I wanted to add mine as it wasn't included in these current suggestions. In order to get the shadows working on both KitKat and Marshmallow, (only emulators I tried, I'm sure it works in between) I added the following xml attributes to my card:

card:cardElevation="25dp"
card:cardUseCompatPadding="true"

After banging my head against my desk for why that wasn't working, trying to set the background color of the card to something completely opaque, enabling hardware acceleration in the manifest, and even praying, I checked the namespace declarations in my file. To my horror, I saw that the card xml namespace had been assigned to the following:

xmlns:card="http://schemas.android.com/tools"

After fixing that namespace declaration, I ran my dummy app again and let out a sigh of relief as shadows were finally being shown as expected.

Here is proof in case you're a doubter like me. And please Google, Android, whoever: Make shadows great again. They shouldn't be this difficult.

enter image description here

Here is the entire file that created the layout pictured below:

<?xml version="1.0" encoding="utf-8"?>

<!--MAKE SURE YOU HAVE THE RIGHT XML NAMESPACE ASSIGNED-->
<!--TO WHATEVER WORD YOU PUT IN FRONT OF THE CARD-->
<!--XML ATTRIBUTES. IN THIS CASE, MINE IS card-->
<android.support.percent.PercentRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:card="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#607D8B"
    android:fitsSystemWindows="true"
    tools:context="com.mlustig.playground.MainActivity">

    <android.support.v7.widget.CardView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        app:layout_aspectRatio="66%"
        app:layout_heightPercent="75%"
        card:cardElevation="25dp"
        card:cardUseCompatPadding="true" />
</android.support.percent.PercentRelativeLayout>

Yes, I know. It's annoying that you can't simply copy and paste this layout and run it because it has PercentRelativeLayout in it, but I left it there on purpose. You should definitely check it out. Super powerful, very useful. Nice nice nice. Hope this helped.

lustig
  • 2,802
  • 17
  • 26
2

As noted earlier, this is an open bug in Android : if the background drawable uses a solid color with transparency, then the shadow won't be shown.

To work around the issue, display the background in its own separate view and set the alpha on that view. Wrap the background view and the TextView in a RelativeLayout to place the background directly under the TextView and use android:layout_alignLeft, android:layout_alignBottom etc to make it the same size. They need to be at the same elevation, and the background must appear before the TextView in the xml so it is drawn under it.

<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingLeft="40dp"
    android:paddingRight="40dp"
    android:paddingTop="20dp"
    android:paddingBottom="20dp"
    android:clipToPadding="false"
    android:background="#ffffff">

    <View
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/text_view"
        android:layout_alignRight="@id/text_view"
        android:layout_alignBottom="@id/text_view"
        android:layout_alignTop="@id/text_view"
        android:background="@drawable/rect"
        android:alpha="0.5"
        android:elevation="8dp"/>


    <TextView
        android:id="@id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hallo world"
        android:textColor="#ffffff"
        android:padding="8dp"
        android:elevation="8dp" />

</RelativeLayout>

The drawable is the same as yours but without transparency:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="#0073ff" />
    <corners android:radius="16dp" />
</shape>

Result:

Result

A few notable points:

  • You must ensure that the enclosing RelativeLayout is large enough to display the shadow. If you just set its dimensions to wrap_content without padding, the shadow will be clipped to the layout's bounds. As explained in this question, you can use padding and set android:cipToPadding="false" to make it large enough for the shadow. You might not need as much padding in this case, I haven't experimented with that.
  • In this case we need to use a separate view for the background because if we had set the alpha directly on the TextView then the text would have been affected as well. Depending on your use case you might not need a separate view and enclosing layout and could just just have one view, with alpha set on the view and no transparency in the drawable.
Samuel Peter
  • 3,696
  • 2
  • 29
  • 36
1

Try using : app:cardElevation="4dp"

imran.razak
  • 178
  • 1
  • 11
0

Try adding margin to the CardView.

Sam Chen
  • 2,491
  • 1
  • 17
  • 31