在今天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


当前回答

要支持彩色按钮,请使用最新的AppCompat库(>23.2.1):

膨胀- XML

AppCompat小部件:

android.support.v7.widget.AppCompatButton

AppCompat风格:

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

NB !在xml中设置自定义颜色:使用attr: app而不是android

(使用alt+输入或声明xmlns:app="http://schemas.android.com/apk/res-auto"使用app)

应用:backgroundTint = " @color / your_custom_color”

例子:

<android.support.v7.widget.AppCompatButton
     style="@style/Widget.AppCompat.Button.Colored"
     app:backgroundTint="@color/your_custom_color"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"     
     android:text="Colored Button"/>

或者以编程方式设置- JAVA

 ViewCompat.setBackgroundTintList(your_colored_button,
 ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));

其他回答

如果你想用任何颜色的代码来做这个:

DrawableCompat.setTintList(button.getBackground(), ColorStateList.valueOf(yourColor));

实际上,我不想改变我的自定义按钮样式,但不幸的是,它们不再工作了。

我的应用程序有一个minSdkVersion 9和一切工作之前。

我不知道为什么,但自从我删除了android:在buttonStyle之前,它似乎又工作了

现在=工作中:

<item name=“buttonStyle”>@style/ButtonmyTime</item>

之前=只是灰色材质按钮:

< name = android: buttonStyle >项目@style ButtonmyTime < - >项目

我没有特殊的文件夹为新的android版本,因为我的按钮是相当平坦的,他们应该看起来在所有android版本相同。

也许有人能告诉我为什么我要删除“机器人”: ImageButton仍在使用“android:”

<item name="android:imageButtonStyle">@style/ImageButtonmyTimeGreen</item>

在寻找答案2天后,在API < 21中按钮主题对我来说不起作用。

我唯一的解决方案是覆盖AppCompatButton着色不仅与基础应用主题“colorButtonNormal”,而且视图backgroundTint如下:

public class AppCompatColorButton extends AppCompatButton {

    public AppCompatColorButton(Context context) {
        this(context, null);
    }

    public AppCompatColorButton(Context context, AttributeSet attrs) {
        this(context, attrs, android.support.v7.appcompat.R.attr.buttonStyle);
    }

    public AppCompatColorButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        if (TintManager.SHOULD_BE_USED) {
            setSupportBackgroundTintList(createButtonColorStateList(getContext(), attrs, defStyleAttr));
        }
    }

    static final int[] DISABLED_STATE_SET = new int[]{-android.R.attr.state_enabled};
    static final int[] FOCUSED_STATE_SET = new int[]{android.R.attr.state_focused};
    static final int[] PRESSED_STATE_SET = new int[]{android.R.attr.state_pressed};
    static final int[] EMPTY_STATE_SET = new int[0];

    private ColorStateList createButtonColorStateList(Context context, AttributeSet attrs, int defStyleAttr) {
        final int[][] states = new int[4][];
        final int[] colors = new int[4];
        int i = 0;

        final int themeColorButtonNormal = ThemeUtils.getThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorButtonNormal);
        /*TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.backgroundTint }, defStyleAttr, 0);
        final int colorButtonNormal = a.getColor(0, themeColorButtonNormal);*/
        TypedArray a = context.obtainStyledAttributes(attrs, android.support.v7.appcompat.R.styleable.View, defStyleAttr, 0);
        final int colorButtonNormal = a.getColor(android.support.v7.appcompat.R.styleable.View_backgroundTint, themeColorButtonNormal);
        a.recycle();
        final int colorControlHighlight = ThemeUtils.getThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorControlHighlight);

        // Disabled state
        states[i] = DISABLED_STATE_SET;
        colors[i] = ThemeUtils.getDisabledThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorButtonNormal);
        i++;

        states[i] = PRESSED_STATE_SET;
        colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
        i++;

        states[i] = FOCUSED_STATE_SET;
        colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
        i++;

        // Default enabled state
        states[i] = EMPTY_STATE_SET;
        colors[i] = colorButtonNormal;
        i++;

        return new ColorStateList(states, colors);
    }
}

然后你可以像这样定义你的按钮颜色:

<com.example.views.AppCompatColorButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:backgroundTint="#ffff0000"
            app:backgroundTint="#ffff0000"
            android:text="Button"
            android:textColor="@android:color/white" />

编辑(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属性自定义他们的背景,如下所述。