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

mai*_*929 245 android button android-button android-view material-design

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

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

显示所需结果的图片

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

这是我之前做的改变以下按钮颜色的方法styles.xml:

<item name="android:colorButtonNormal">insert color here</item>
Run Code Online (Sandbox Code Playgroud)

并动态地做:

button.getBackground().setColorFilter(getResources().getColor(insert color here), PorterDuff.Mode.MULTIPLY);
Run Code Online (Sandbox Code Playgroud)

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

Win*_*der 221

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

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

用法示例

theme.xml:

<item name="colorButtonNormal">@color/button_color</item>
Run Code Online (Sandbox Code Playgroud)

V21/theme.xml

<item name="android:colorButtonNormal">@color/button_color</item>
Run Code Online (Sandbox Code Playgroud)

  • 使用AppCompat 22.1.1,它仅对一个按钮也适用于2.3.7,4.4.4和5.1:设置按钮的'android:theme ="@ style/ColoredButton"`,以及styles.xml` <style name = "ColoredButton"parent ="Widget.AppCompat.Button"> <item name ="colorButtonNormal"> @ color/button_yellow </ item> </ style> (71认同)
  • 有没有任何例子如何使用它?如何只在一个按钮上设置颜色? (17认同)
  • @WindRider我有一个问题,我想用它来创建不同颜色的按钮.我创建样式Button.Red,Button.Green,所有都使用父等于Button基本样式.我将itemButtonNormal设置为请求的颜色,将其设置为按钮主题.不幸的是它只有21的颜色按钮.它下面没有覆盖主题中定义的colorButtonNormal. (3认同)
  • @gladed:在您的情况下,问题似乎是这个错误:https://code.google.com/p/android/issues/detail?id = 62795#c1 (3认同)
  • @hunyadym,由于某种原因,在按钮上添加一个主题.我会将此归类为解决方法,直到Design库提供更好的方法. (2认同)

elu*_*eci 148

编辑(22.06.2016):

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

原答案:

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

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

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

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

可绘制-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>
Run Code Online (Sandbox Code Playgroud)

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

当你意识到这个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>
Run Code Online (Sandbox Code Playgroud)

3 - 获取材料按钮的尺寸

在此文件中,您可以在此处找到文件使用的某些维度.您可以复制整个文件并将其放入您的values文件夹中.这对于将相同尺寸(在材质按钮中使用)应用于所有按钮非常重要

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

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

绘制/ 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>
Run Code Online (Sandbox Code Playgroud)

结果

您的按钮会对Lollipop设备产生连锁反应.除了涟漪效应之外,旧版本将具有完全相同的按钮.但既然你为不同的状态提供了绘图,他们也会回应触摸事件(就像旧的方式).

  • 我完全同意你的看法.Button是最常用的小部件,但它不包含在材料的支持库中.我不知道他们在想什么. (39认同)
  • 非常烦人,不支持开箱即用 (7认同)
  • 对,就是这样.如果您对所有按钮使用相同的背景,并且如果您不想一次又一次地添加它,请在styles.xml中定义按钮样式**<style name ="ButtonStyle"parent ="android:Widget.Button" > <item name ="android:background"> @ drawable/custom_btn </ item> </ style>**并在主题中添加按钮样式**<item name ="android:buttonStyle"> @ style/ButtonStyle </项目>** (4认同)

Muh*_*ifi 109

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

Widget.AppCompat.Button.Colored

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

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

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

    compileSdkVersion = 23
    targetSdkVersion = 23
Run Code Online (Sandbox Code Playgroud)

In your values/theme

<item name="android:buttonStyle">@style/BrandButtonStyle</item>
Run Code Online (Sandbox Code Playgroud)

In your values/style

<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="colorButtonNormal">@color/yourButtonColor</item>
    <item name="android:textColor">@color/White</item>
</style>
Run Code Online (Sandbox Code Playgroud)

In your 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>
Run Code Online (Sandbox Code Playgroud)

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

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 :)

<Button
        android:layout_width="200dp"
        android:layout_height="48dp" />
Run Code Online (Sandbox Code Playgroud)

Disabled State 禁用状态

Enabled State 启用状态

  • 现在,这是最好的方法!您还可以使用`<Button android:theme ="@ style/BrandButtonStyle"/>`在单个按钮上使用该样式.它必须是`theme`属性和_not_`style`属性. (18认同)
  • 使用v23.1 lib,这不能正常工作,当尝试将其设置为整个主题时,它总是将重音颜色显示为bg,而不是定义的颜色 (8认同)
  • @Muhammad Alfaifi你有样品项目或要点吗?我创建了干净的项目,它不起作用:https://github.com/Bresiu/ThemeTest.在带有强调色的Lolipop按钮颜色和API v16上,按钮保持灰色:http://i.imgur.com/EVwkpk2.png (7认同)
  • 这在指定属性android:theme时仅对我有用.我无法通过按钮标记获取属性样式. (4认同)
  • 同样的问题,在v23.1上,禁用按钮与启用按钮的颜色相同.很沮丧.有谁想到这个? (3认同)

小智 62

在Android支持库22.1.0中,Google Button明白了这一点.因此,另一种自定义按钮背景颜色的方法是使用该backgroundTint属性.

例如,

<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" />
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,这仅适用于API 21+.即使使用AppCompat库,android:backgroundTint属性也不适用于pre-Lollipop.只有来自主题的colorButtonNormal才能在pre-Lollipop上运行. (19认同)
  • 文档说:"当你在布局中使用Button时,这将自动使用.你应该只需要在编写自定义视图时手动使用这个类." http://developer.android.com/reference/android/support/v7/widget/AppCompatButton.html这是否意味着我们不必手动更改所有布局和Java代码? (5认同)

Tou*_*der 40

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

膨胀 - XML

AppCompat小部件:

android.support.v7.widget.AppCompatButton
Run Code Online (Sandbox Code Playgroud)

AppCompat风格:

style="@style/Widget.AppCompat.Button.Colored"
Run Code Online (Sandbox Code Playgroud)

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

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

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"/>
Run Code Online (Sandbox Code Playgroud)

或以编程方式设置它 - JAVA

 ViewCompat.setBackgroundTintList(your_colored_button,
 ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));
Run Code Online (Sandbox Code Playgroud)


小智 25

使用最新的支持库,您可以继承自己的活动AppCompatActivity,因此它会ButtonAppCompatButton您的内容充气,并让您有机会使用以下内容为布局上的每个按钮设置颜色样式android:theme="@style/SomeButtonStyle",其中SomeButtonStyle:

<style name="SomeButtonStyle" parent="@android:style/Widget.Button">
    <item name="colorButtonNormal">@color/example_color</item>
</style>
Run Code Online (Sandbox Code Playgroud)

在2.3.7,4.4.1,5.0.2中为我工作

  • 谢谢你,也为我工作过.确保使用`android:theme`而不是`style`.您还可以添加`colorControlHighlight`和`colorControlActivated`. (3认同)

Jin*_*inu 16

如果你想要低于风格

在此输入图像描述

添加此样式您的按钮

style="@style/Widget.AppCompat.Button.Borderless.Colored"
Run Code Online (Sandbox Code Playgroud)

如果你想要这种风格

在此输入图像描述

添加以下代码

style="@style/Widget.AppCompat.Button.Colored"
Run Code Online (Sandbox Code Playgroud)


小智 14

答案是主题而不是风格

问题是Button颜色贴在主题的colorButtonNormal上.我试图以很多不同的方式改变风格而没有运气.所以我改变了按钮主题.

使用colorButtonNormal和colorPrimary创建主题:

<style name="ThemeAwesomeButtonColor" parent="AppTheme">
    <item name="colorPrimary">@color/awesomePrimaryColor</item>
    <item name="colorButtonNormal">@color/awesomeButtonColor</item>
</style>
Run Code Online (Sandbox Code Playgroud)

按钮中使用此主题

<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"/>
Run Code Online (Sandbox Code Playgroud)

"AppTheme.Button"可以是任何扩展Button样式的东西,就像这里我使用原色来表示文字颜色:

<style name="AppTheme.Button" parent="Base.Widget.AppCompat.Button">
    ...
    <item name="android:textColor">?attr/colorPrimary</item>
    ...
</style>
Run Code Online (Sandbox Code Playgroud)

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