Material effect on button with background color

2020-01-22 13:49发布

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

16条回答
Animai°情兽
2楼-- · 2020-01-22 14:06

The @ianhanniballake's answer is absolutely correct and simple. But it took me few days to understand. For someone who don't understand his answer, here is more detail implementation

<Button
        android:id="@+id/btn"
        style="@style/MaterialButton"
        ... />


<style name="MaterialButton" parent="Widget.AppCompat.Button.Colored">
    <item name="android:theme">@style/Theme.MaterialButton</item>
   ...
</style>


<style name="Theme.MaterialButton" parent="YourTheme">
    <item name="colorAccent">@color/yourAccentColor</item>
    <item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>

===Or===

<Button
        android:id="@+id/btn"
        style="@style/Widget.AppCompat.Button.Colored"
        android:theme="@style/Theme.MaterialButton" />

<style name="Theme.MaterialButton" parent="YourTheme">
    <item name="colorAccent">@color/yourAccentColor</item>
    <item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>
查看更多
闹够了就滚
3楼-- · 2020-01-22 14:06

There are two approaches explained in the great tutorial be Alex Lockwood: http://www.androiddesignpatterns.com/2016/08/coloring-buttons-with-themeoverlays-background-tints.html:

Approach #1: Modifying the button’s background color w/ a ThemeOverlay

<!-- res/values/themes.xml -->
<style name="RedButtonLightTheme" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">@color/googred500</item>
</style>

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:theme="@style/RedButtonLightTheme"/>

Approach #2: Setting the AppCompatButton’s background tint

<!-- res/color/btn_colored_background_tint.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Disabled state. -->
    <item android:state_enabled="false"
          android:color="?attr/colorButtonNormal"
          android:alpha="?android:attr/disabledAlpha"/>

    <!-- Enabled state. -->
    <item android:color="?attr/colorAccent"/>

</selector>

<android.support.v7.widget.AppCompatButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:backgroundTint="@color/btn_colored_background_tint"/>
查看更多
虎瘦雄心在
4楼-- · 2020-01-22 14:07

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.

查看更多
Juvenile、少年°
5楼-- · 2020-01-22 14:08

If you're ok with using a third party library, check out traex/RippleEffect. It allows you to add a Ripple effect to ANY view with just a few lines of code. You just need to wrap, in your xml layout file, the element you want to have a ripple effect with a com.andexert.library.RippleView container.

As an added bonus it requires Min SDK 9 so you can have design consistency across OS versions.

Here's an example taken from the libraries' GitHub repo:

<com.andexert.library.RippleView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:rv_centered="true">

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@android:drawable/ic_menu_edit"
        android:background="@android:color/holo_blue_dark"/> 

</com.andexert.library.RippleView>

You can change the ripple colour by adding this attribute the the RippleView element: app:rv_color="@color/my_fancy_ripple_color

查看更多
萌系小妹纸
6楼-- · 2020-01-22 14:09

Use backgroundTint instead of background

查看更多
何必那么认真
7楼-- · 2020-01-22 14:12

I tried this:

android:backgroundTint:"@color/mycolor"

instead of changing background property. This does not remove the material effect.

查看更多
登录 后发表回答