Material effect on button with background color
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.
There is another simple solution to provide custom background for "Flat" buttons while keeping their "Material" effects.
- Place your button in ViewGroup with desired background set there
- set selectableItemBackground from current theme as background for your button (API >=11)
i.e. :
<FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/blue"> <Button style="?android:attr/buttonStyleSmall" android:background="?android:attr/selectableItemBackground" android:textColor="@android:color/white" android:textAllCaps="true" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Button1" /></FrameLayout>
Can be used for Flat buttons, it works on API >=11, and you will get ripple effect on >=21 devices, keeping regular buttons on pre-21 till AppCompat is updated to support ripple there as well.
You can also use selectableItemBackgroundBorderless for >=21 buttons only.
Here is a simple and backward compatible way to deliver ripple effect to raised buttons with the custom background.
Your layout should look like this
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/my_custom_background" android:foreground="?android:attr/selectableItemBackground"/>