Android appcompat-v7:21.0.0 更改Material复选框颜色

64

我已经更新了我的项目,使用了最新的appcompat支持库,新版本使用了Material Design复选框和单选按钮。我的应用程序是深色主题,复选框是黑色的,很难看到。我正在尝试根据Maintaining Compatibility更改它们的颜色,但目前还没有任何作用。

res/values/styles.xml

  <style name="AppBaseTheme" parent="@style/Theme.AppCompat.Light">

    <!-- customize the color palette -->
    <item name="colorAccent">@color/silver</item>
  </style>

在 build.gradle 文件中:

    android {
      compileSdkVersion 21
      buildToolsVersion '21.1.1'

      defaultConfig {
        minSdkVersion 9
        targetSdkVersion 19
      }
    }

.....
.....    

    compile 'com.android.support:appcompat-v7:21.0.0'

AndroidManifest.xml:

  <application
      android:name="ee.mtakso.App"
      android:allowBackup="true"
      android:icon="@drawable/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppBaseTheme">

复选框、编辑文本框、单选按钮等仍然是黑色的。

编辑

我不知道这是否有太大的区别,但我使用的单选按钮和复选框是用于CheckedTextView的,如下:

单选按钮:android:checkMark="?android:attr/listChoiceIndicatorSingle"

多选框:android:checkMark="?android:attr/listChoiceIndicatorMultiple"

由于它们得到了黑色材质的可绘制对象,我认为问题并不是来自它们。


你在其他的Values文件夹(例如values-v14)中改变了样式吗? - Arash GM
你要检查哪个版本的安卓系统?14级以下?还是14级以上? - Harsha Vardhan
@Arash 不,我已经删除了 values-v14 等内容,所以这个 styles.xml 是唯一的。 - Nima GT
@HarshaVardhan 上面,测试在4.4.2上。 - Nima GT
我认为这是appcompat-lib中的一个bug。我在版本22.1.0中遇到了同样的问题。更新到22.1.1后,小部件着色又可以正常工作了。 - Christopher
18个回答

127

我遇到了与未选中的复选框和单选按钮类似的问题。当我发现控件从以下代码中获取它们的“关闭”颜色时,我找到了解决方案:

<item name="android:textColorSecondary">@color/secondary_text</item>


编辑:

如果您的应用程序或活动主题继承了L的AppCompat(Dark / Light / Light.DarkActionBar)之一,则可以设置:

<style name="SampleTheme" parent="Theme.AppCompat">
    <item name="colorAccent">@color/green</item>
    <item name="android:textColorSecondary">@color/red</item>
</style>

这是结果:

图片描述

注意:当你获得不同的效果时,你可能使用了"错误"的主题 - 确保正确设置。


10
这在 Android 4.4.4 上无法正常工作。CheckBoxes 和 RadioButtons 仍然是黑色的。 - Etienne Lawlor
1
我已经确认在KitKat(确切地说是4.4.4版本)上可以运行。同时,4.3、4.4.2和5.0.1的效果也很好。我已经编辑了我的回答,请查看我的提示,也许对你有所帮助。 - paulina_glab
2
我的问题是,我希望CheckBoxesRadioButtons都在文本的右侧。因此,我尝试为CheckBox使用属性android:button="@null"android:drawableRight="?android:attr/listChoiceIndicatorMultiple",并为RadioButton使用属性android:button="@null"android:drawableRight="?android:attr/listChoiceIndicatorSingle"。但是,在Pre-Lollipop设备上,android:button="@null"似乎会剥离AppCompat主题中这些小部件的任何小部件着色。 - Etienne Lawlor
android:textColorSecondary 除了复选框和单选按钮以外还用于样式化哪些其他的小部件? - andrew
是的,例如 SeekBar 条的右侧。但是,我不能保证支持库在每种情况下都能按您的要求工作 - 老实说,我不这么认为 :) [这种颜色也用于着色 Toolbar 的图标,但对于 Toolbar,我们可以提供主题,因此很容易进行覆盖。] 我觉得 Google 认为改变这些颜色(除了强调)并不重要,只需将它们与主题保持一致即可。我的问题恰恰相反:我设置了 android:textColorSecondary(用于 Toolbar,在创建第二个主题之前),但我不希望我的小部件使用它作为它们的次要颜色。 - paulina_glab
显示剩余7条评论

37

我认为这是AppCompat主题中的一个错误。我的解决方法是在xml布局文件中向每个复选框添加两行代码。

android:button="@drawable/abc_btn_check_material"
android:buttonTint="@color/colorAccent"

你永远不应该直接引用abc_drawables,但在这种情况下,我找不到其他解决方案。

这也适用于RadioButton小部件!您只需使用abc_btn_radio_material而不是abc_btn_check_material


1
太棒了!使用Tint并将其设置为主要颜色,可以正确地为UI设置主题 :-) - Someone Somewhere
这不会改变涟漪效果的颜色。 - Waza_Be
@Waza_Be 我需要再次测试...可能是SDK特定的问题。 - Codeversed
1
@Waza_Be,如果你想要更改涟漪效果的颜色,请将以下代码添加到你的主题中:<item name="colorControlHighlight">@color/yourRippleColor</item> - blueware

18

我这样做是为了至少改变复选框的边框:

<style name="checkBoxComponent" parent="AppTheme">
    //Checked color
    <item name="colorAccent">@color/blueBackground</item> 
    //Checkbox border color
    <item name="android:textColorSecondary">@color/grayBorder</item> 
</style>

而在我的布局中

<android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:theme="@style/checkBoxComponent"
                        android:text="Yay" />

还在努力想办法获取复选框的背景。 希望对你有所帮助。


这对我来说可行。但是有一个警告,就是AppCompatCheckBox在Android 5和6上似乎无法正常工作(它会崩溃)。因此,在这些Android版本上必须使用常规的CheckBox。 - Mr-IDE
优秀的解决方案,可以更改单个组件的主题,而不是整个应用程序中的所有组件(就像接受的答案一样)。也可用于(我的)常规复选框和 android:button="@null"android:drawableRight="?android:attr/listChoiceIndicatorMultiple" 的情况,这也是一些评论中要求的! - P Kuijpers

14

我有和你一样的问题。 我再次查看了AppCompat v21—适用于早期版本的材料设计!

我发现这句话:"您的所有活动必须扩展自ActionBarActivity,它从v4支持库的FragmentActivity扩展,因此您可以继续使用片段。".

所以我将我的活动更改为ActionBarActivity,解决了我的问题。希望它也能解决你的问题。


我所有的活动都已经从ActionBarActivity派生出来。我只是在升级compat lib,发现在5.0上运行应用程序一切都很完美,但后来意识到在任何4.x设备上表现不如预期,复选框几乎不可见,并且当我切换到全黑背景而不是默认和丑陋的灰色时,它们完全不可见。 - 3c71
1
另一个需要注意的问题是,在为列表视图填充视图时,确保从您的ActionBarActivity创建inflater,而不是从任何其他上下文(包括getBaseContext())创建。因此,在创建适配器时,请记得将“this”作为上下文传递。 - Glenn.nz
1
这对我来说是正确的修复方法。请注意,似乎支持库中的“ActionBarActivity”已被弃用,改为使用“AppCompatActivity”。 - TechnalyticSteve

8
我已经找到了一个解决方案。 步骤1:扩展ActionBarActivity。
public static class MyActivity extends ActionBarActivity {
        //...
}

第二步
在您的样式文件中编写两个值

<style name="MyTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="colorAccent">#009688</item>
        <item name="android:textColorSecondary">#757575</item>
</style>

colorAccent -选中时的颜色
android:textColorSecondary -未选中时的颜色

第三步
在AndroidManifest.xml中设置您的主题。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.test.radiobutton"
          android:versionCode="1"
          android:versionName="1.0">
    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">

                    ....

        <activity android:name=".activity.MyActivity "
                  android:theme="@style/MyTheme"/>

                  .....

    </application>
</manifest>


结果
Android 5
android_5
Android 4.2.2
android_4.2.2

注:此处为IT技术相关内容,无需更多解释。

这没有帮助我。我必须在每个RadioButton/CheckBox中添加app:buttonTint="?attr/colorAccent"。 - Emanuel Moecklin

7

1. 在styles.xml文件中声明自定义样式。

<style name="CustomStyledRadioButton" parent="Theme.AppCompat.Light">
    <item name="colorControlNormal">@color/red</item>
    <item name="colorControlActivated">@color/red_pressed</item>
</style>

2. 通过 android:theme 属性将此样式应用于您的 RadioButton。

  <RadioButton  android:id="@+id/rb_option1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:checked="true"
    android:gravity="left"
    android:lineSpacingExtra="10dp"
    android:padding="10dp"
    android:text="Option1"
    android:textColor="@color/black"
    android:theme="@style/CustomStyledRadioButton"/>

你的父主题以 .Light 结尾,这会使得它在显示上变得困难。如果你移除父主题,它将能够在 AppCompat 的浅色和深色主题下正常工作。 - blueware

7

百分之百有效

只需为您的单选按钮创建一个样式,并像下面这样更改colorAccent:

<style name="RadioButtonTeal" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorAccent">@color/md_teal_600</item>
</style>

然后,只需将此样式添加到您的AppCompatRadioButton中:
<android.support.v7.widget.AppCompatRadioButton
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:theme="@style/RadioButtonTeal" />

这似乎是有效的。但是你可能会发现在Android 5和6上,AppCompatRadioButton会导致崩溃。因此,在这些Android版本上,你必须使用普通的RadioButton。 - Mr-IDE

4

为了指定颜色,请覆盖以下内容:

选中颜色:

<item name="android:colorControlActivated">@color/your_color</item> 

对于未选中的颜色:

<item name="android:colorControlNormal">@color/your_color</item>

3
您会遇到兼容性库与复选框和单选按钮的许多问题。
1)对于任何Android 4.x设备,它们仅以黑色出现。它们在Android 5.x和2.x上运行良好(不要问我为什么在2.x上运行良好,我不知道)。
2)它们没有禁用状态(如果所有复选框都已启用,则无所谓,否则您将面临非常糟糕的惊喜)。
请注意,默认的深色主题背景是灰色而不是黑色,因此如果您保持默认设置,它是“可以”的。
为了解决这个问题,我创建了以下绘制的白色和禁用版本,并将其添加到我的核心项目中,但未添加到兼容项目中(出于明显的维护目的)。
abc_btn_check_to_on_mtrl_000
abc_btn_check_to_on_mtrl_015
abc_btn_radio_to_on_mtrl_000
abc_btn_radio_to_on_mtrl_015

接着创建了一个可维护所有状态的drawable(以覆盖兼容原始状态):

例如,暗黑主题将使用此选项:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:state_checked="true" android:drawable="@drawable/abc_btn_check_to_on_mtrl_015_disabled" />
    <item android:state_enabled="true" android:state_checked="true" android:drawable="@drawable/abc_btn_check_to_on_mtrl_015" />
    <item android:state_enabled="true" android:drawable="@drawable/abc_btn_check_to_on_mtrl_000" />
    <item android:drawable="@drawable/abc_btn_check_to_on_mtrl_000_disabled" />
</selector>

浅色主题将使用这个(用户可以在我的应用中切换主题):

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:state_checked="true" android:drawable="@drawable/abc_btn_check_to_on_mtrl_015_disabled" />
    <item android:state_enabled="true" android:state_checked="true" android:drawable="@drawable/abc_btn_check_to_on_mtrl_015_light" />
    <item android:state_enabled="true" android:drawable="@drawable/abc_btn_check_to_on_mtrl_000_light" />
    <item android:drawable="@drawable/abc_btn_check_to_on_mtrl_000_disabled" />
</selector>

接下来我所需要做的就是覆盖默认的兼容主题(包括活动和对话框,无论是浅色还是深色主题),添加类似于以下内容的代码:

    <item name="android:listChoiceIndicatorSingle">@drawable/abc_btn_radio_material</item>
    <item name="android:listChoiceIndicatorMultiple">@drawable/abc_btn_check_material</item>

这是针对浅色主题的内容:

    <item name="android:listChoiceIndicatorSingle">@drawable/abc_btn_radio_material_light</item>
    <item name="android:listChoiceIndicatorMultiple">@drawable/abc_btn_check_material_light</item>

现在我已经在每个Android版本上拥有完全操作的复选框和单选按钮了!在我看来,兼容库在暗黑主题方面根本没有得到测试,只使用了白色主题。兼容库的开发者很可能从未使用过禁用状态。


但是这在使用setMultiChoiceItems(...)填充的AlertDialogs(Android 4.x)上不起作用!它们仍然是Holo风格的复选框... :( - silversmurf
确实如此。为了解决这个问题,您需要在ListView“即时”更换,我在我的项目中已经完成了这个操作,但这是另一个问题,并需要对AlertDialog类进行非常复杂的“hack”。 - 3c71
设置色调颜色似乎已经在appcompat 22.1中得到修复:http://developer.android.com/tools/support-library/index.html - Hrk

2
只需像这样扩展 ActionBarActivity
Public class MainActivity extends ActionBarActivity {

//...

}

如果您扩展任何标准视图,则必须扩展TintXX,例如TintCheckBox。或者,如果您不想扩展ActionBarActivity,则可以直接从中复制onCreateView方法。 - pablisco

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