DEV Community

Mostafa Gazar
Mostafa Gazar

Posted on • Updated on

Beautiful Android rounded buttons

Let us say the designer in your team handed you this beautifully custom button to implement.

It looks nice, it flat, not much to it really. Should be easy to implement.


First you create a StateListDrawable , easy!

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

    <item android:state_pressed="true">
        <shape android:shape="rectangle">

            <solid android:color="@color/color_dhuhr_background_pressed" />

            <corners
                android:topRightRadius="@dimen/default_event_end_corner"
                android:bottomRightRadius="@dimen/default_event_end_corner"
                android:topLeftRadius="@dimen/default_event_start_corner"
                android:bottomLeftRadius="@dimen/default_event_start_corner"/>

        </shape>
    </item>

    <item>
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@color/color_dhuhr_background" />

                    <corners
                        android:bottomLeftRadius="@dimen/default_event_start_corner"
                        android:bottomRightRadius="@dimen/default_event_end_corner"
                        android:topLeftRadius="@dimen/default_event_start_corner"
                        android:topRightRadius="@dimen/default_event_end_corner" />

                </shape>
            </item>

            <item android:gravity="left">
                <shape android:shape="rectangle">
                    <solid android:color="@color/color_dhuhr_background_pressed" />

                    <size android:width="4dp" />
                </shape>
            </item>
        </layer-list>
    </item>

</selector>
Enter fullscreen mode Exit fullscreen mode

You run the app and you get this

Did you notice the ugly shadows?


This must be happening because of elevation or z index.


An easy solution would be to use borderless button style, Widget.AppCompat.Button.Borderless. This would mean though that that button will not raise when the user taps it.

I do not think that looks great.


There is another solution, which is to use Widget.AppCompat.Button and override stateListAnimator with our own animation.

<style name="Button.Event" parent="Widget.AppCompat.Button">
    <item name="android:stateListAnimator">@animator/button_event_animator</item>
</style>
Enter fullscreen mode Exit fullscreen mode

button_event_animator.xml

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

    <item android:state_pressed="true">
        <set>
            <objectAnimator android:propertyName="translationZ"
                            android:duration="@integer/button_event_pressed_animation_duration"
                            android:valueTo="@dimen/button_event_pressed_z"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="elevation"
                            android:duration="0"
                            android:valueTo="@dimen/button_event_pressed_elevation"
                            android:valueType="floatType"/>
        </set>
    </item>

    <item>
        <set>
            <objectAnimator android:propertyName="translationZ"
                            android:duration="0"
                            android:valueTo="0"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="elevation"
                            android:duration="0"
                            android:valueTo="0"
                            android:valueType="floatType"/>
        </set>
    </item>

</selector>
Enter fullscreen mode Exit fullscreen mode

The end result would look

This look like something intractable.


Thanks for reading! Stay updated.

Top comments (0)