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 backgro
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.
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.
Try using : app:cardElevation="4dp"
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>
Try adding margin to the CardView
.
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:
A few notable points:
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.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.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">