使用 Material Design 和 AppCompat 为 Android 中的按钮着色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26519979/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:40:45  来源:igfitidea点击:

Coloring Buttons in Android with Material Design and AppCompat

androidbuttonandroid-viewandroid-buttonmaterial-design

提问by mail929

Before the AppCompatupdate came out today I was able to change the color of buttons in Android L but not on older versions. After including the new AppCompat update I am unable to change the color for either version, when I do try the button just disappears. Does anyone know how to change the button color?

AppCompat今天更新发布之前,我可以更改 Android L 中按钮的颜色,但不能更改旧版本中的按钮颜色。在包含新的 AppCompat 更新后,我无法更改任一版本的颜色,当我尝试时该按钮就会消失。有谁知道如何更改按钮颜色?

The following pictures shows what I want to achieve:

以下图片显示了我想要实现的目标:

picture showing desired result

显示所需结果的图片

The white button is default, the red one is what I want.

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

This is what I was doing previously to change the color of the buttons in the styles.xml:

这是我之前所做的更改 中按钮颜色的操作styles.xml

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

and to do it dynamically:

并动态地做到这一点:

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

Also I did change the theme parent from @android:style/Theme.Material.Light.DarkActionBarto Theme.AppCompat.Light.DarkActionBar

我也确实将主题父项从 更改@android:style/Theme.Material.Light.DarkActionBarTheme.AppCompat.Light.DarkActionBar

采纳答案by WindRider

Officially fixed in Support Library rev.22 (Fri March 13, 2015). See relevant google code issue:

在支持库 rev.22 中正式修复(2015 年 3 月 13 日星期五)。查看相关的谷歌代码问题:

https://issuetracker.google.com/issues/37008632

https://issuetracker.google.com/issues/37008632

Usage example

使用示例

theme.xml:

主题.xml:

<item name="colorButtonNormal">@color/button_color</item>

v21/theme.xml

v21/theme.xml

<item name="android:colorButtonNormal">@color/button_color</item>

回答by eluleci

Edit (22.06.2016):

编辑(22.06.2016):

Appcompatlibrary started to support material buttons after I posted the original response. In this postyou can see the easiest implementation of raised and flat buttons.

在我贴出原始响应后,Appcompat库开始支持材质按钮。在这篇文章中,您可以看到凸起和平面按钮的最简单实现。

Original Answer:

原答案:

Since that AppCompat doesn't support the button yet you can use xml as backgrounds. For doing that I had a look at the source code of the Android and found the related files for styling material buttons.

由于该 AppCompat 不支持按钮,因此您可以使用 xml 作为背景。为此,我查看了 Android 的源代码并找到了样式材料按钮的相关文件。

1 - Look at the original implementation of material button from source.

1 - 从源代码查看材质按钮的原始实现。

Have a look at the btn_default_material.xml on android source code.

看看android 源代码上的btn_default_material.xml

You can copy the file into your projects drawable-v21 folder. But don't touch the color attr here. The file you need to change is the second file.

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

drawable-v21/custom_btn.xml

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 - Get the shape of the original material button

2 - 获取原始素材按钮的形状

As you realise there is a shape used inside this drawable which you can find in this file of the source code.

当你意识到在这个 drawable 中使用了一个形状,你可以在源代码的这个文件中找到

<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 - Getting dimensions of the material button

3 - 获取材质按钮的尺寸

And in this file you there are some dimensions used from the file that you can find here. You can copy the whole file and put into your valuesfolder. This is important for applying the same size (that is used in material buttons) to all buttons

在此文件中,您可以在此处找到文件使用的一些尺寸。您可以复制整个文件并放入您的文件夹。这对于将相同的大小(用于材质按钮)应用于所有按钮很重要

4 - Create another drawable file for old versions

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

For older versions you should have another drawable with the same name. I am directly putting the items inline instead of referencing. You may want to reference them. But again, the most important thing is the original dimensions of the material button.

对于旧版本,您应该有另一个同名的 drawable。我直接将项目内联而不是引用。您可能想参考它们。但同样,最重要的是材质按钮的原始尺寸。

drawable/custom_btn.xml

可绘制/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>

Result

结果

Your button will have ripple effect on Lollipop devices. The old versions will have exactly same button except the ripple effect. But since that you provide drawables for different states, they'll also respond to touch events (as the old way).

您的按钮将对 Lollipop 设备产生连锁反应。除了波纹效果外,旧版本将具有完全相同的按钮。但是由于您为不同的状态提供了可绘制对象,它们也会响应触摸事件(像旧方式一样)。

回答by Muhammad Alfaifi

This has been enhanced in v23.0.0 of AppCompat library with the addition of more themes including

这在 AppCompat 库的 v23.0.0 中得到了增强,添加了更多主题,包括

Widget.AppCompat.Button.Colored

Widget.AppCompat.Button.Colored

First of all include appCompat dependency if you haven't already

首先,如果您还没有包含 appCompat 依赖项

compile('com.android.support:appcompat-v7:23.0.0') {
    exclude group: 'com.google.android', module: 'support-v4'
}

now since you need to use v23 of the app compat, you'll need to target SDK-v23 as well!

现在,由于您需要使用应用程序兼容的 v23,因此您还需要以 SDK-v23 为目标!

    compileSdkVersion = 23
    targetSdkVersion = 23

In your values/theme

在你的 values/theme

<item name="android:buttonStyle">@style/BrandButtonStyle</item>

In your values/style

在你的 values/style

<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="colorButtonNormal">@color/yourButtonColor</item>
    <item name="android:textColor">@color/White</item>
</style>

In your values-v21/style

在你的 values-v21/style

<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="android:colorButtonNormal">@color/yourButtonColor</item>
    <item name="android:textColor">@color/White</item>
</style>

Since your button theme is based on Widget.AppCompat.Button.ColoredThe text color on the button is by default white!

由于您的按钮主题基于按钮上Widget.AppCompat.Button.Colored的文本颜色默认为白色!

but it seems there is an issue when you disable the button, the button will change its color to light grey, but the text color will remain white!

但是当您禁用该按钮时似乎存在问题,该按钮会将其颜色更改为浅灰色,但文本颜色将保持为白色!

a workaround for this is to specifically set the text color on the button to white! as I have done in the style shown above.

解决方法是将按钮上的文本颜色专门设置为白色!正如我在上面显示的样式中所做的那样。

now you can simply define your button and let AppCompat do the rest :)

现在你可以简单地定义你的按钮,让 AppCompat 做剩下的事情:)

<Button
        android:layout_width="200dp"
        android:layout_height="48dp" />

Disabled State Disabled state

禁用状态 禁用状态

Enabled State Enabled State

启用状态 启用状态

Edit:

编辑:

To add <Button android:theme="@style/BrandButtonStyle"/>

加上 <Button android:theme="@style/BrandButtonStyle"/>

回答by Manabu-GT

In Android Support Library 22.1.0, Google made the Buttontint aware. So, another way to customise the background color of button is to use the backgroundTintattribute.

在 Android 支持库 22.1.0 中,GoogleButton意识到了色调。因此,另一种自定义按钮背景颜色的方法是使用该backgroundTint属性。

For example,

例如,

<Button
       android:id="@+id/add_remove_button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:backgroundTint="@color/bg_remove_btn_default"
       android:textColor="@android:color/white"
       tools:text="Remove" />

回答by TouchBoarder

To support colored buttons use the latest AppCompat library (>23.2.1) with:

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

inflate - XML

膨胀 - XML

AppCompat Widget:

AppCompat 小工具:

android.support.v7.widget.AppCompatButton

AppCompat Style:

应用兼容风格:

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

NB!To set a custom color in xml: use the attr: appinstead of android

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

(use alt+enteror declare xmlns:app="http://schemas.android.com/apk/res-auto"to use app)

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

app:backgroundTint="@color/your_custom_color"

应用程序:backgroundTint="@color/your_custom_color"

Example:

例子:

<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"/>

orset it programmatically - JAVA

或以编程方式设置 - JAVA

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

回答by Artem

With latest Support Library you could just inherit you activity from AppCompatActivity, so it will inflate your Buttonas AppCompatButtonand give you an opportunity to style color of every single button on the layout with using of android:theme="@style/SomeButtonStyle", where SomeButtonStyleis:

使用最新的支持库,您可以从 继承您的活动AppCompatActivity,因此它会扩展您的ButtonasAppCompatButton并让您有机会使用 of 来设置布局上每个按钮的样式颜色android:theme="@style/SomeButtonStyle",其中SomeButtonStyle是:

<style name="SomeButtonStyle" parent="@android:style/Widget.Button">
    <item name="colorButtonNormal">@color/example_color</item>
</style>

Worked for me in 2.3.7, 4.4.1, 5.0.2

在 2.3.7、4.4.1、5.0.2 为我工作

回答by Jinu

if you want below style

如果你想要下面的风格

enter image description here

在此处输入图片说明

add this style your button

添加此样式您的按钮

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

if you want this style

如果你想要这种风格

enter image description here

在此处输入图片说明

add below code

添加下面的代码

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

回答by lonelyboycs

The answer is in THEMEnot style

答案是主题而不是风格

The problem is that the Button color is stick to the colorButtonNormal of the theme. I have tried to change the Style in many different ways with no luck. So I changed the button theme.

问题是 Button 颜色与主题的 colorButtonNormal 一致。我试图以许多不同的方式改变风格,但没有运气。所以我改变了按钮主题

Create a theme with colorButtonNormal and colorPrimary:

使用 colorButtonNormal 和 colorPrimary 创建一个主题:

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

Use this theme in button

在按钮中使用此主题

<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"/>

The "AppTheme.Button" can be any thing extends Button style like here I use primary color for text color:

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

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

And you get the button in any color you want that compatible to material design.

并且您可以获得与材料设计兼容的任何颜色的按钮。

回答by ingyesid

this work for me with appcompat-v7:22.2.0 in android + 4.0

这对我来说适用于 android + 4.0 中的 appcompat-v7:22.2.0

in your styles.xml

在你的styles.xml

<style name="Button.Tinted" parent="Widget.AppCompat.Button">
    <item name="colorButtonNormal">YOUR_TINT_COLOR</item>
    <item name="colorControlHighlight">@color/colorAccent</item>
    <item name="android:textColor">@android:color/white</item>
</style>

in your layout file

在您的布局文件中

<Button
    android:id="@+id/but_next"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/but_continue"
    android:theme="@style/Button.Tinted" />

回答by BArtWell

Layout:

布局:

<android.support.v7.widget.AppCompatButton
  style="@style/MyButton"
  ...
  />

styles.xml:

样式.xml:

<style name="MyButton" parent="Widget.AppCompat.Button.Colored">
  <item name="backgroundTint">@color/button_background_selector</item>
  <item name="android:textColor">@color/button_text_selector</item>
</style>

color/button_background_selector.xml:

颜色/button_background_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="#555555"/>
    <item android:color="#00ff00"/>
</selector>

color/button_text_selector.xml:

颜色/button_text_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="#888888"/>
    <item android:color="#ffffff"/>
</selector>