在今天AppCompat更新出来之前,我可以改变Android L中按钮的颜色,但在旧版本上不行。在包含新的AppCompat更新后,我无法更改两个版本的颜色,当我尝试时,按钮就消失了。有人知道怎么改变按钮的颜色吗?

下面的图片展示了我想要达到的目标:

白色按钮是默认的,红色按钮是我想要的。

这是我之前在styles.xml中改变按钮颜色所做的:

<item name="android:colorButtonNormal">insert color here</item>

要动态地进行:

button.getBackground().setColorFilter(getResources().getColor(insert color here), PorterDuff.Mode.MULTIPLY);

我也改变了@android:style/ theme . material . light的主题父元素。到Theme.AppCompat.Light.DarkActionBar


当前回答

我用这个。波纹效果和按钮点击阴影工作。

style.xml

<style name="Button.Red" parent="Widget.AppCompat.Button.Colored">
    <item name="android:textColor">@color/material_white</item>
    <item name="android:backgroundTint">@color/red</item>
</style>

布局按钮:

<Button
        style="@style/Button.Red"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/close"/>

其他回答

对于那些使用ImageButton的人,下面是如何做到这一点:

在style.xml:

<style name="BlueImageButton" parent="Base.Widget.AppCompat.ImageButton">
    <item name="colorButtonNormal">@color/primary</item>
    <item name="android:tint">@color/white</item>
</style>

在v21 / style.xml:

<style name="BlueImageButton" parent="Widget.AppCompat.ImageButton">
    <item name="android:colorButtonNormal">@color/primary</item>
    <item name="android:tint">@color/white</item>
</style>

然后在布局文件中:

<android.support.v7.widget.AppCompatImageButton
    android:id="@+id/my_button"
    android:theme="@style/BlueImageButton"
    android:layout_width="42dp"
    android:layout_height="42dp"
    android:layout_gravity="center_vertical"
    android:src="@drawable/ic_check_black_24dp"
    />

答案是主题,而不是风格

问题是Button的颜色与主题的colorButtonNormal一致。我尝试过很多不同的方法来改变风格,但都没有成功。所以我改变了按钮的主题。

用colorButtonNormal和colorPrimary创建一个主题:

<style name="ThemeAwesomeButtonColor" parent="AppTheme">
    <item name="colorPrimary">@color/awesomePrimaryColor</item>
    <item name="colorButtonNormal">@color/awesomeButtonColor</item>
</style>

在按钮中使用此主题

<Button
        android:id="@+id/btn_awesome"
        style="@style/AppTheme.Button"
        android:theme="@style/ThemeAwesomeButtonColor"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_awesome"/>

“AppTheme。按钮”可以是任何东西扩展按钮样式,就像这里我使用原色作为文本颜色:

<style name="AppTheme.Button" parent="Base.Widget.AppCompat.Button">
    ...
    <item name="android:textColor">?attr/colorPrimary</item>
    ...
</style>

你可以得到你想要的任何颜色的按钮,与材料设计兼容。

我设置android:textColor @null在我的按钮主题,它有帮助。

styles.xml

<style name="Button.Base.Borderless" parent="Widget.AppCompat.Button.Borderless.Colored">
    <item name="android:textColor">@null</item>
</style>

some_layout.xml

<Button
    style="@style/Button.Base.Borderless"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hint" />

现在按钮文本颜色是在AppTheme中定义的colorAccent

<style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <item name="colorAccent">@color/colorAccent</item>
    <item name="borderlessButtonStyle">@style/Button.Base.Borderless</item>
    <item name="alertDialogTheme">@style/AlertDialog</item>
</style>

编辑(22.06.2016):

Appcompat库开始支持材料按钮后,我张贴了原始的回应。在这篇文章中,你可以看到凸起和扁平按钮的最简单实现。

最初的回答:

因为AppCompat还不支持按钮,你可以使用xml作为背景。为了做到这一点,我查看了Android的源代码,并找到了样式化材质按钮的相关文件。

1 -从源头看材料按钮的原始实现。

看看android上的btn_default_material.xml源代码。

您可以将该文件复制到项目drawable-v21文件夹中。但是不要碰这里的颜色。您需要更改的文件是第二个文件。

drawable-v21 / custom_btn.xml

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?attr/colorControlHighlight">
    <item android:drawable="@drawable/btn_default_mtrl_shape" />
</ripple>

2 -获得原始材料按钮的形状

正如你意识到的那样,在这个可绘制的图形中使用了一个形状,你可以在这个源代码文件中找到它。

<inset xmlns:android="http://schemas.android.com/apk/res/android"
   android:insetLeft="@dimen/button_inset_horizontal_material"
   android:insetTop="@dimen/button_inset_vertical_material"
   android:insetRight="@dimen/button_inset_horizontal_material"
   android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
    <corners android:radius="@dimen/control_corner_material" />
    <solid android:color="?attr/colorButtonNormal" />
    <padding android:left="@dimen/button_padding_horizontal_material"
             android:top="@dimen/button_padding_vertical_material"
             android:right="@dimen/button_padding_horizontal_material"
             android:bottom="@dimen/button_padding_vertical_material" />
</shape>

3 -获取材料按钮的尺寸

在这个文件中你可以找到文件中用到的一些维度。您可以复制整个文件并将其放入values文件夹中。这对于将相同的尺寸(用于材质按钮)应用到所有按钮是很重要的

4 -为旧版本创建另一个可绘制文件

对于旧版本,您应该有另一个具有相同名称的可绘制对象。我直接把项目内联而不是引用。你可能想要引用它们。但同样,最重要的是材质按钮的原始尺寸。

可拉的/ custom_btn.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
    <!-- pressed state -->
    <item android:state_pressed="true">
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/PRESSED_STATE_COLOR" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
    
    <!-- focused state -->
    <item android:state_focused="true">
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/FOCUSED_STATE_COLOR" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
    
    <!-- normal state -->
    <item>
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/NORMAL_STATE_COLOR" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
</selector>

结果

你的按钮会在棒棒糖设备上产生连锁反应。旧版本将有完全相同的按钮,除了涟漪效应。但是因为你为不同的状态提供了可绘制对象,它们也会响应触摸事件(就像旧的方式一样)。

如果你只想要“平面”材质按钮,你可以使用selectableItemBackground属性自定义他们的背景,如下所述。