Search code examples
androidandroid-5.0-lollipop

Material effect on button with background color


I am using Android v21 support library.

I have created a button with custom background color. The Material design effects like ripple, reveal are gone (except the elevation on click) when I use the back ground color.

 <Button
 style="?android:attr/buttonStyleSmall"
 android:background="?attr/colorPrimary"
 android:textColor="@color/white"
 android:textAllCaps="true"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Button1"
 />

Background The following is a normal button and the effects are working just fine.

<Button
 style="?android:attr/buttonStyleSmall"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:textAllCaps="true"
 android:text="Button1"
/>

Default button


Solution

  • When you use android:background, you are replacing much of the styling and look and feel of a button with a blank color.

    Update: As of the version 23.0.0 release of AppCompat, there is a new Widget.AppCompat.Button.Colored style which uses your theme's colorButtonNormal for the disabled color and colorAccent for the enabled color.

    This allows you apply it to your button directly via

    <Button
      ...
      style="@style/Widget.AppCompat.Button.Colored" />
    

    If you need a custom colorButtonNormal or colorAccent, you can use a ThemeOverlay as explained in this pro-tip and android:theme on the button.

    Previous Answer

    You can use a drawable in your v21 directory for your background such as:

    <?xml version="1.0" encoding="utf-8"?>
    <ripple xmlns:android="http://schemas.android.com/apk/res/android"
            android:color="?attr/colorControlHighlight">
        <item android:drawable="?attr/colorPrimary"/>
    </ripple>
    

    This will ensure your background color is ?attr/colorPrimary and has the default ripple animation using the default ?attr/colorControlHighlight (which you can also set in your theme if you'd like).

    Note: you'll have to create a custom selector for less than v21:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@color/primaryPressed" android:state_pressed="true"/>
        <item android:drawable="@color/primaryFocused" android:state_focused="true"/>
        <item android:drawable="@color/primary"/>
    </selector>
    

    Assuming you have some colors you'd like for the default, pressed, and focused state. Personally, I took a screenshot of a ripple midway through being selected and pulled the primary/focused state out of that.