How can I emulate button elevation (shadow) in Android API lower than 21?
Asked Answered
F

2

10

I have this minimal Android Studio project with just a button. I assign the button a shadow with:

android:elevation="3dp"
android:translationZ="3dp"
android:stateListAnimator="@null"

and I see the shadow in Android Studio Design tab. But I also get a warning in the xml editor

Atribute ... is only used in API level 21 and higher (current min is 16)

And indeed, button shadow is displayed only in emulators with API level 21 or higher, and it is shown flat, with no shadow at all in emulators with API level lower than 21.

So the concrete question is, how can I emulate the shadow effect in API's lower than 21.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <LinearLayout
        android:id="@+id/main_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:weightSum="1">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="20dp"
            android:layout_weight="2.24">

            <Button
                android:id="@+id/my_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_marginLeft="20dp"
                android:layout_marginBottom="20dp"
                android:elevation="5dp"
                android:translationZ="5dp"
                android:stateListAnimator="@null"
                android:background="@android:color/holo_green_light"
                android:text="BUTTON"/>

        </RelativeLayout>
    </LinearLayout>
</ScrollView>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

}

Button showing shadow, in API 22: enter image description here

Same button not showing shadow, in API 16: enter image description here

Fieldfare answered 9/7, 2016 at 7:33 Comment(0)
H
12

For Pre-LolliPop device you have to Create shadow or elevation using drawable file. This way.

Create drawable file in your folder like element_background.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item>
    <shape android:shape="rectangle">
        <solid android:color="#BDBDBD"/>
        <corners android:radius="5dp"/>
    </shape>
</item>

<item
    android:left="0dp"
    android:right="0dp"
    android:top="0dp"
    android:bottom="2dp">
    <shape android:shape="rectangle">
        <solid android:color="#ffffff"/>
        <corners android:radius="5dp"/>
    </shape>
</item>
</layer-list>

Then add the following code to the element to which you want.

android:background="@drawable/element_background"
Hards answered 9/7, 2016 at 7:44 Comment(1)
Yes @Ironman, it works. But it requires a lot of work dealing with button pressed, focusted, etc. So I'm leaving button appearance as it was intended to be by Google in each API. Thanks!Fieldfare
C
6

If you wish, you can try Carbon. It's a library backporting material features back to 2.2. It supports elevation and generated, animated shadows as well.

https://github.com/ZieIony/Carbon

Coif answered 10/7, 2016 at 22:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.