【问题标题】:Coloring Buttons in Android with Material Design and AppCompat使用 Material Design 和 AppCompat 在 Android 中为按钮着色
【发布时间】:2014-12-18 15:25:01
【问题描述】:

在今天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.DarkActionBar 更改为 Theme.AppCompat.Light.DarkActionBar

【问题讨论】:

  • 我尝试了同样的方法,但没有改变按钮的颜色。我还从属性中删除了 android: 因为它来自支持库而不是 android 命名空间的一部分
  • 如果您在 Android 5.0 中使用 android:colorButtonNormal 它可以工作 - 但它似乎不向后兼容
  • 是的,这正是我所经历的
  • 我还发现强调色不会改变 CheckBox 颜色,但在旧版本中会改变
  • 为该动态方法加一个。 :)

标签: android button android-view android-button material-design


【解决方案1】:

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

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

使用示例

主题.xml:

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

v21/theme.xml

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

【讨论】:

  • 有没有示例如何使用?如何仅在一个 Button 上设置颜色?
  • @WindRider 我有一个问题,我想用它来创建不同颜色的按钮。我创建样式 Button.Red、Button.Green,所有样式都具有父级等于 Button 基本样式。我将项目 colorButtonNormal 设置为请求的颜色,将其设置为按钮主题。不幸的是,它只为 21 的按钮着色。下面它不会覆盖主题中定义的 colorButtonNormal。
  • 使用 AppCompat 22.1.1 它在 2.3.7、4.4.4 和 5.1 上也适用于一个按钮:设置按钮的 android:theme="@style/ColoredButton" 和 styles.xml &lt;style name="ColoredButton" parent="Widget.AppCompat.Button"&gt; &lt;item name="colorButtonNormal"&gt;@color/button_yellow&lt;/item&gt; &lt;/style&gt;
  • @hunyadym,为按钮添加主题会因某种原因中断 onClick。在设计库提供更好的方法之前,我会将其归类为一种解决方法。
  • @gladed:在您的情况下,问题似乎是这个错误:code.google.com/p/android/issues/detail?id=62795#c1
【解决方案2】:

编辑(22.06.2016):

Appcompat 库在我发布原始回复后开始支持材质按钮。 In this post 你可以看到凸起和扁平按钮的最简单实现。

原答案:

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

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

看看btn_default_material.xml on android source code

您可以将文件复制到您的项目 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 - 获取原始材质按钮的形状

当您意识到此可绘制对象内部使用了一个形状时,您可以在 this file of the source code 中找到它。

<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 - 获取材质按钮的尺寸

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

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

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

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>

结果

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

【讨论】:

  • 是的。如果您对所有按钮使用相同的背景并且不想一次又一次地添加它,请在您的 styles.xml 并在您的主题中添加按钮样式 @style /ButtonStyle
  • 如何在 pre-21 上为这个按钮添加高程?据我了解,我应该在按钮下方添加带有阴影的新形状,但我应该把它放在哪里?
  • 开箱即用不支持这很烦人
  • 我完全同意你的看法。按钮是最常用的小部件,但它不包含在材质的支持库中。我不知道他们在想什么。
  • 另外,按照您的指南,背景似乎根本没有出现......
【解决方案3】:

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

Widget.AppCompat.Button.Colored

如果你还没有的话,首先包括 appCompat 依赖

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

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

    compileSdkVersion = 23
    targetSdkVersion = 23

在你的values/theme

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

在你的values/style

<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="colorButtonNormal">@color/yourButtonColor</item>
    <item name="android:textColor">@color/White</item>
</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>

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

但是当你禁用按钮时似乎有一个问题,按钮将其颜色变为浅灰色,但文本颜色将保持白色!

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

现在您可以简单地定义您的按钮,让 AppCompat 完成剩下的工作 :)

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

禁用状态

启用状态

编辑:

添加&lt;Button android:theme="@style/BrandButtonStyle"/&gt;

【讨论】:

  • 这是最好的方法,现在!您还可以通过 &lt;Button android:theme="@style/BrandButtonStyle"/&gt; 在单个按钮上使用该样式。它必须是theme 属性,而不是 style 属性。
  • @Muhammad Alfaifi 你有这方面的示例项目或要点吗?我创建了干净的项目,但它不起作用:github.com/Bresiu/ThemeTest。在带有强调色的 Lolipop 按钮颜色和 API v16 中,按钮保持灰色:i.imgur.com/EVwkpk2.png
  • 这仅在指定属性 android:theme 时对我有效。我无法使用按钮标签让属性样式为我工作。
  • 使用 v23.1 lib,这不能正常工作,当尝试将其设置为整个主题时,它总是将强调色显示为 bg,而不是定义的颜色
  • 同样的问题,在 v23.1 上,禁用按钮的颜色与启用按钮的颜色相同。非常令人沮丧。有人知道吗?
【解决方案4】:

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

【讨论】:

  • 终于!关于 22.1 版本的博文:android-developers.blogspot.no/2015/04/…
  • 文档说:“当你在布局中使用 Button 时,这将自动使用。你应该只需要在编写自定义视图时手动使用这个类。” developer.android.com/reference/android/support/v7/widget/… 这是否意味着我们不必手动更改所有布局和 java 代码?
  • @Stephane 不,我们应该改变布局。 chris.banes.me/2015/04/22/support-libraries-v22-1-0
  • 太棒了!现在,是否有一个 AppCompatToggleButton 可以让您更改 ToggleButtons 的背景?也许我可以抄袭代码...
  • 不幸的是,这只适用于 API 21+。即使使用 AppCompat 库, android:backgroundTint 属性也不适用于 pre-Lollipop。只有来自主题的 colorButtonNormal 可以在棒棒糖之前使用。
【解决方案5】:

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

膨胀 - XML

AppCompat 小部件:

android.support.v7.widget.AppCompatButton

AppCompat 样式:

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

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

(使用alt+enter 或声明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));

【讨论】:

  • 您的 Java 代码对我有用。并且 Muhammad Alfaifi 的回答帮助设置了按钮的文本颜色。
  • 有没有一种简单的方法来以编程方式设置色调(不是背景)?
  • 太棒了!也适用于 4.4.4!并且选择器状态也保持得相当好!
  • Per the docs:在布局中设置按钮时会自动使用它。您只需要在创建自定义视图时指定 AppCompatButton。
  • 有趣的是,XML 更改在片段中完美运行,但在 Activity 布局中却不行。活动按钮仅使用 colorAccent。程序化版本虽然有效。
【解决方案6】:

使用最新的支持库,您可以从AppCompatActivity 继承您的活动,因此它将您的Button 膨胀为AppCompatButton,并让您有机会使用@987654324 设置布局上每个按钮的颜色@,其中SomeButtonStyle 是:

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

在 2.3.7、4.4.1、5.0.2 中为我工作

【讨论】:

  • 谢谢!!!我刚刚更改了“Widget.AppCompat.EditText”的父值,因为我需要更新 EditText 样式。
  • 谢谢,也为我工作。确保使用android:theme 而不是style。您也可以添加colorControlHighlightcolorControlActivated
  • 不起作用,API 22,AppCompatActivity,主题 Material.Light
  • @AndreyUglev 尝试使用Theme.AppCompat.Light
  • 嗨,它改变了所需的颜色,但去除了阴影。
【解决方案7】:

如果你想要下面的样式

将此样式添加到您的按钮

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

如果你想要这种风格

添加以下代码

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

【讨论】:

  • compile 'com.android.support:appcompat-v7:23.1.0'你一定要加。
  • 但问题是如何有不同颜色的材质按钮,让不是所有的都有主题的原色。
【解决方案8】:

答案是主题而不是风格

问题是按钮颜色坚持主题的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.Button”可以是任何扩展按钮样式的东西,比如这里我使用原色作为文本颜色:

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

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

【讨论】:

  • 我可以在样式中添加哪些其他属性。
【解决方案9】:

我刚刚创建了一个 android 库,可以让您轻松修改按钮颜色和波纹颜色

https://github.com/xgc1986/RippleButton

<com.xgc1986.ripplebutton.widget.RippleButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btn"
    android:text="Android button modified in layout"
    android:textColor="@android:color/white"
    app:buttonColor="@android:color/black"
    app:rippleColor="@android:color/white"/>

您不需要为每个按钮创建不同颜色的样式,允许您随机自定义颜色

【讨论】:

    【解决方案10】:

    这适用于我在 android + 4.0 中使用 appcompat-v7:22.2.0

    在你的 style.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>
    

    在你的布局文件中

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

    【讨论】:

    • 嗨,它改变了所需的颜色,但去除了阴影。
    • 您好,我可以看到。现在是正确的行为。
    • 如何在 Java 中做到这一点?
    • @MicroR 检查上面的答案。
    【解决方案11】:

    布局:

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

    styles.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>
    

    颜色/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>
    

    颜色/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>
    

    【讨论】:

      【解决方案12】:

      对于那些使用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"
          />
      

      【讨论】:

      • 这有帮助....我想重要的是要注意将按钮样式应用为主题而不是按钮小部件中的样式。我在 style="@style/BlueImageButton" 下应用它,但它不起作用
      【解决方案13】:

      如果您将样式解决方案与 colorButtonNormal 一起使用,请不要忘记从 Widget.AppCompat.Button.Colored 继承,这样波纹效果才会起作用;)

      喜欢

      <style name="CustomButtonStyle" parent="Widget.AppCompat.Button.Colored">
            <item name="colorButtonNormal">@android:color/white</item>
      </style>
      

      【讨论】:

        【解决方案14】:

        我用这个。涟漪效果和按钮单击阴影工作。

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

        【讨论】:

          【解决方案15】:

          另一个使用 AppCompatButton 的简单解决方案

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

          【讨论】:

            【解决方案16】:

            用途:

            android:backgroundTint="@color/customColor"
            

            甚至:

            android:background="@color/customColor"
            

            这将为按钮提供自定义颜色。

            【讨论】:

              【解决方案17】:

              如果您只想要“平面”材质按钮,您可以使用selectableItemBackground 属性自定义其背景,如here 所述。

              【讨论】:

              • 如果您不想更改任何“色调”颜色或选定颜色,这绝对是一个简单的解决方案,仍然可以通过彩色按钮获得反馈。谢谢!
              【解决方案18】:

              改变单个按钮的颜色

              ViewCompat.setBackgroundTintList(button, getResources().getColorStateList(R.color.colorId));
              

              【讨论】:

                【解决方案19】:

                对我来说,问题是在 Android 5.0 中 android:colorButtonNormal 没有效果,实际上,主题中没有任何项目(如 android:colorAccent),但在 Android 4.4.3 中,例如,没有效果。该项目使用compileSdkVersiontargetSdkVersion 配置为22,所以我已经按照@Muhammad Alfaifi 的建议进行了所有更改,但最后,我注意到问题出在buildToolsVersion,没有更新。一旦我更改为 23.0.1,一切都开始正常工作。现在,android:colorButtonNormal 仍然没有效果,但至少按钮对android:colorAccent 有反应,这对我来说是可以接受的。

                我希望这个提示可以帮助某人。 注意:我已经将样式直接应用到按钮上,因为按钮的android:theme=[...] 也没有效果。

                【讨论】:

                【解决方案20】:

                实现这一点的一种方法是让您只指向一种样式,而不是为应用中的所有按钮设置相同主题。
                在themes.xml 中添加一个主题

                    <style name="Theme.MyApp.Button.Primary.Blue" parent="Widget.AppCompat.Button">
                        <item name="colorButtonNormal">@color/someColor</item>
                        <item name="android:textColorPrimary">@android:color/white</item>
                    </style>
                

                现在在styles.xml 中添加

                    <style name="MyApp.Button.Primary.Blue" parent="">
                        <item name="android:theme">@style/Theme.MyApp.Button.Primary.Blue</item>
                    </style>
                

                现在在您的布局中只需指向按钮中的样式

                    <Button
                        ...
                        style="@style/MyApp.Button.Primary.Blue"
                        ...  />
                

                【讨论】:

                  【解决方案21】:

                  更新

                  使用 design support library(23.2.0)appcompatwidgets 如下

                  In Android Support Library 22.1

                  这是在扩展布局时自动完成的 - 替换 Button 与 AppCompatButton、TextView 与 AppCompatTextView 等确保 每个都可以支持着色。在这个版本中,那些色彩意识 小部件现在是公开可用的,让您可以继续着色 支持,即使您需要子类化其中一个受支持的小部件。

                  色彩感知小部件的完整列表:

                  AppCompatAutoCompleteTextView
                  AppCompatButton
                  AppCompatCheckBox
                  AppCompatCheckedTextView
                  AppCompatEditText
                  AppCompatMultiAutoCompleteTextView
                  AppCompatRadioButton
                  AppCompatRatingBar
                  AppCompatSpinner
                  AppCompatTextView
                  

                  Material Design for Pre-Lollipop Devices

                  AppCompat(又名 ActionBarCompat)最初是作为 适用于在 Gingerbread 上运行的设备的 Android 4.0 ActionBar API, 在反向移植的实现之上提供一个通用 API 层 和框架实现。 AppCompat v21 提供了一个 API 和 与 Android 5.0 保持同步的功能集


                  【讨论】:

                    【解决方案22】:

                    如果你想使用像 Widget.AppCompat.ButtonBase.Widget.AppCompat.Button.Colored 等 AppCompat 风格,你需要使用这些风格与支持库中的兼容视图。

                    以下代码不适用于棒棒糖之前的设备:

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

                    您需要使用 AppCompatButton 来启用 AppCompat 样式:

                    <android.support.v7.widget.AppCompatButton
                       android:layout_width="wrap_content"
                       android:layout_height="wrap_content"
                       android:theme="@style/Widget.AppCompat.Button" />
                    

                    【讨论】:

                    • 在扩展 XML 布局时是否会自动使用应用兼容小部件?我相信ImageView 会被AppCompatImageView 取代,并且它应该与所有具有相应AppCompat 版本的小部件相同。
                    • 不行,如果你不定位最后一个目标版本,你需要明确定义android.support.v7.widget.AppCompatImageView
                    • last target version、@power 是什么意思?
                    【解决方案23】:

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

                    我的应用的 minSdkVersion 为 9,之前一切正常。

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

                    现在 = 工作:

                    &lt;item name="buttonStyle"&gt;@style/ButtonmyTime&lt;/item&gt;

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

                    &lt;item name="android:buttonStyle"&gt;@style/ButtonmyTime&lt;/item&gt;

                    我没有用于 newver android 版本的特殊文件夹,因为我的按钮非常扁平,并且它们在所有 android 版本中看起来都应该相同。

                    也许有人可以告诉我为什么我必须删除“android:” ImageButton 仍在使用“android:”

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

                    【讨论】:

                      【解决方案24】:

                      在寻找答案 2 天后,API

                      我唯一的解决方案是覆盖 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" />
                      

                      【讨论】:

                        【解决方案25】:

                        这个 SO 答案帮助我找到了答案 https://stackoverflow.com/a/30277424/3075340

                        我使用这个实用方法来设置按钮的背景色调。它适用于棒棒糖之前的设备:

                        // Set button background tint programmatically so it is compatible with pre-lollipop devices.
                        public static void setButtonBackgroundTintAppCompat(Button button, ColorStateList colorStateList){
                            Drawable d = button.getBackground();
                            if (button instanceof AppCompatButton) {
                                // appcompat button replaces tint of its drawable background
                                ((AppCompatButton)button).setSupportBackgroundTintList(colorStateList);
                            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                // Lollipop button replaces tint of its drawable background
                                // however it is not equal to d.setTintList(c)
                                button.setBackgroundTintList(colorStateList);
                            } else {
                                // this should only happen if
                                // * manually creating a Button instead of AppCompatButton
                                // * LayoutInflater did not translate a Button to AppCompatButton
                                d = DrawableCompat.wrap(d);
                                DrawableCompat.setTintList(d, colorStateList);
                                button.setBackgroundDrawable(d);
                            }
                        
                        }
                        

                        如何在代码中使用:

                        Utility.setButtonBackgroundTintAppCompat(myButton,
                        ContextCompat.getColorStateList(mContext, R.color.your_custom_color));
                        

                        这样,如果您只想更改背景色调,而无需指定 ColorStateList,只需保持漂亮的按钮效果等等。

                        【讨论】:

                          【解决方案26】:

                          我在按钮主题中将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" />
                          

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

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

                          【讨论】:

                            【解决方案27】:

                            如果您想通过任何颜色的代码执行此操作,请使用:

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

                            【讨论】:

                              【解决方案28】:

                              就我而言,我没有使用 Button,而是使用 androidx.appcompat.widget.AppCompatButton 它对我有用。

                              【讨论】:

                                猜你喜欢
                                • 2015-08-20
                                • 2015-01-31
                                • 2019-11-17
                                • 2016-07-06
                                • 2015-02-06
                                • 2014-12-08
                                • 1970-01-01
                                • 1970-01-01
                                • 2015-02-23
                                相关资源
                                最近更新 更多