在v21之前如何给复选框着色

24

因此,我希望将色彩应用于AppCompat复选框。

在Lollipop上一切都运行良好:

android:buttonTint="@color/purple_FF4081"

或者这样:

android:theme="@style/Theme.MyTheme.PurpleAccent"

但是设置任何这些参数都不会改变早于Lollipop版本的内容。只有在我设置应用程序主题的colorAccent时才有效。但我不想让所有小部件都改变外观,只想改变一个复选框的外观。 有没有一种方法可以在不设置彩色可绘制对象的情况下实现这一点?

5个回答

64

快速提醒一下,自从 AppCompatActivity 和新的支持库引入之后,所有这些都已经改变了,参考(这里以漂亮的方式概述)可以通过使用 theme 属性并设置 colorControlNormalcolorControlActivated 来给复选框着色:

styles.xml

<style name="MyCheckBox" parent="Theme.AppCompat.Light">  
<item name="colorControlNormal">@color/indigo</item>
<item name="colorControlActivated">@color/pink</item>
</style> 

布局XML:

<CheckBox  
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="true"
        android:text="Check Box"
        android:theme="@style/MyCheckBox"/>

这太棒了!一直在寻找这个答案。顺便问一下,复选框的默认颜色是什么?如果我想让正常状态成为默认颜色,那会是什么颜色?我尝试过“@null”,但没有效果。 - Red M
你应该得到一枚奖章! - Sadiq Md Asif
不确定这是否应该是答案,因为我收到了一个警告,它需要API 21,而问题明确说明是pre 21。除非我做错了什么! - Mark A. Donohoe
那些无法正常工作的人可能正在尝试使用自定义镜像,因为这种方法不起作用。 - Kenny

25

您可以直接在xml中设置颜色。对于框,使用buttonTint属性:(自API级别23起)

<CheckBox
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:buttonTint="@color/CHECK_COLOR" />

您也可以使用v7的appCompatCheckbox来为旧版本API实现此操作:

<android.support.v7.widget.AppCompatCheckBox 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    app:buttonTint="@color/COLOR_HERE" />

非常感谢您的回答 :) - shakunthalaMK
它不起作用。我已经检查过了。+ 如果AppCompat*小部件没有动态创建,它们会自动应用。 - Slava

11

我需要通过程序来完成它,经过一番搜索之后,我终于找到了这个解决方案(在Kitkat和Marshmallow上测试通过),我只是为了帮助有需要的人而发布:

public static void setAppCompatCheckBoxColors(final AppCompatCheckBox _checkbox, final int _uncheckedColor, final int _checkedColor) {
    int[][] states = new int[][]{new int[]{-android.R.attr.state_checked}, new int[]{android.R.attr.state_checked}};
    int[] colors = new int[]{_uncheckedColor, _checkedColor};
    _checkbox.setSupportButtonTintList(new ColorStateList(states, colors));
}

对我没用。无论我提供什么颜色,它始终为选中和未选中状态下的灰色。我按如下方式调用函数:'setAppCompatCheckBoxColors(checkBox, R.color.simple_red, R.color.colorPrimary);',其中我使用 'AppCompatCheckBox checkBox = new AppCompatCheckBox(context);' 创建了复选框。 - Zvi
2
你正在使用颜色资源ID,应该直接指定颜色本身,像这样:'setAppCompatCheckBoxColors(checkBox, Color.YELLOW, Color.RED);' 或者在你的实例中像这样:'setAppCompatCheckBoxColors(checkBox, activity.getResources().getColor(R.color.simple_red), activity.getResources().getColor(R.color.colorPrimary));' - androidseb
@jzeferino:你编辑了我的答案,并将“int [] [] states = new int [] [] {new int [] {-android.R.attr.state_checked},new int [] {android.R.attr.state_checked}};”更改为“int [] [] states = new int [] [] {new int [] {android.R.attr.state_checked},new int [] {android.R.attr.state_checked}};”。这个更改似乎使代码不再起作用了,请问你能解释一下这个更改的原因吗? - androidseb
与此同时,我已将代码恢复为我的原始答案。 - androidseb
调用setAppCompatCheckBoxColors(checkBox, Color.YELLOW, Color.GREEN)成功地将复选框在未选中时着色为黄色,在选中时着色为绿色?我测试了您的修改,未选中状态根本不会呈现,当未选中时,复选框会变得不可见。 - androidseb
3
使用新的支持库,你应该使用以下代码:CompoundButtonCompat.setButtonTintList(_checkbox, new ColorStateList(states, colors)); 该代码用于设置复选框的颜色。请确保导入了正确的支持库。 - Patrick Boos

2

我尝试了所有的答案,但只有这个对我有效。在整个活动(或应用程序)的基本样式中添加属性colorControlNormalcolorControlActivated,并从控制器中删除主题。

以下是示例:

    <style name="AppTheme" parent="AppTheme.Base"/>

  <style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">

         <!-- colorPrimary is used for the default action bar background -->
        <item name="colorPrimary">@color/colorPrimary</item>

        <!-- colorPrimaryDark is used for the status bar -->
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>

        <!-- colorAccent is used as the default value for colorControlActivated,
             which is used to tint widgets -->
        <item name="colorAccent">@color/colorAccent</item>
      <!-- to hide white screen in start of window -->
      <item name="android:windowIsTranslucent">true</item>

     <item name="colorControlNormal">@color/orange_two</item>
      <item name="colorControlActivated">@color/pumpkin_orange</item>


    </style>

您的清单

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"> // here is the style used 
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

1

2016年6月28日更新:以下回答已不再正确。请查看有关使用appcompat库在v21之前的设备上允许着色的新方法的被接受的答案。


原始回答:

简短的回答是:不行。自定义的可绘制对象需要在v21之前的设备上创建。这是因为特殊的色调感知小部件目前被隐藏,因为它们是一个未完成的实现细节(谷歌表示,根据他们的开发者博客中的FAQ部分可能会在未来改变)

有两种情况下可以重写colorAccent以使其生效:

  • 拥有自己的小部件版本(即您已扩展EditText)
  • 创建没有LayoutInflater的EditText(即调用new EditText())。

2
我看到谷歌在小部件着色方面说: 您无需采取任何特殊措施即可使其正常工作,只需像往常一样在布局中使用这些控件,AppCompat 将会处理剩下的事情。 - bluebyte
是的,如果您在应用程序style.xml中定义了colorAccent,Android将使用AppCompat覆盖颜色方案。但正如我所说,目前的AppCompat只能是全局的或无效的。 - opt05
很遗憾,他们现在已经添加了在任何视图上设置主题的功能(例如,您可以反转复选框的主题以在相反的颜色上工作),但似乎在应用兼容库中不起作用。此外,您可以设置按钮的tinit,但这仅适用于21+ :( - Daniel Wilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接