android:elevation doesn't work in L preview

IvonLiu picture IvonLiu · Jul 11, 2014 · Viewed 12.6k times · Source

I've been playing with the L preview for a few days, and one thing that doesn't seem to work is the android:elevation attribute for a view. It works just fine when calling View.setElevation(), but it just seems to ignore the XML attribute. I'm using Android Studio 0.8.2 and have minSdkVersion and targetSdkVersion set to 'L', and compileSdkVersion set to 'android-L'. buildToolsVersion is "20.0.0". Here is a sample layout that doesn't work properly:

<?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"
    android:orientation="vertical">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_margin="10dp"
        android:elevation="5dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="top"/>

    </android.support.v7.widget.CardView>

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_margin="10dp"
        android:elevation="0dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="bottom"/>

    </android.support.v7.widget.CardView>

</LinearLayout>

Here is a screenshot of the result: imgur.com/mqeq9vK

According to the android:elevation I set, the bottom card should be flat on the "ground", but it isn't. In fact, it looks no different than the top card who's elevation is 5dp. Is this a known issue, and does it work for you?

EDIT: It seems this is only the case with CardView, or at least it isn't an issue with Buttons. In this layout I replaced CardView with Button, and even though the shadow is kind of screwed up (known bug), you can still see the difference in elevation.

<?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"
    android:orientation="vertical">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:elevation="2dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:elevation="1dp"/>

</LinearLayout>

EDIT 2: It's pretty much confirmed that this issue only affects CardView, android:elevation works fine for any other view. For a detailed explanation of why this happens look at the accepted answer. In the meantime, my workaround is to replace the CardView with a FrameLayout and set android:background to a drawable. Here is an example of a card background drawable that works:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <solid android:color="#fff" />
</shape>

I've also filed this as a bug, so please star this issue if it affects you. https://code.google.com/p/android-developer-preview/issues/detail?id=731

Answer

alanv picture alanv · Jul 11, 2014

CardView sets its own elevation during initialization, which will override whatever you set from XML. You should file this as a bug at https://code.google.com/p/android-developer-preview/wiki/FilingIssues?tm=3

@Override
public void initialize(CardViewDelegate cardView, Context context, int backgroundColor,
        float radius) {
    cardView.setBackgroundDrawable(new RoundRectDrawable(backgroundColor, radius));
    View view = (View) cardView;
    view.setClipToOutline(true);
    view.setElevation(context.getResources().getDimension(R.dimen.cardview_elevation));
}