64

I've updated my project to use the latest appcompat support library, the new version uses material design checkboxes and radio buttons. My app is dark themed and the checkboxes are black which is hard to see. I'm trying to change their colors according to Maintaining Compatibility but so far nothing works.

res/values/styles.xml

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

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

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

The checkboxes, editTexts, radiobuttons etc. remain black.

Edit

I don't know if this makes much difference, but the radiobuttons and checkboxes I'm using are for a CheckedTextView, as following:

Single (radio button): android:checkMark="?android:attr/listChoiceIndicatorSingle"

Multi (check box): android:checkMark="?android:attr/listChoiceIndicatorMultiple"

Since these get the black colored material drawable, I don't think the issue is coming from them.

Nima
  • 6,383
  • 7
  • 46
  • 68

18 Answers18

127

I had a similar problem with unchecked CheckBoxes and RadioButtons. I found the solution, when I figured out that controls takes their "Off" color from

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


EDIT:

Specifying, if your app's or activity's theme inherite one of L's AppCompat (Dark/Light/Light.DarkActionBar), you can set:

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

And that's result:

enter image description here

Notice: When you get different effect you probably use "wrong" theme - make sure you set it correctly.

paulina_glab
  • 2,467
  • 2
  • 16
  • 25
  • 10
    This doesn't work on Android 4.4.4 . The CheckBoxes and RadioButtons remain black. – Etienne Lawlor Jan 15 '15 at 23:50
  • 1
    I'd made sure on KitKat (exactly 4.4.4, device) and it works. Also 4.3, 4.4.2 and 5.0.1 look fine. I've already edited my answer - check my notice, maybe this will help you. – paulina_glab Jan 16 '15 at 12:48
  • 2
    So my problem is, I want both `CheckBoxes` and `RadioButtons` to be on the right side of the text. So I tried using the attributes `android:button="@null"` and `android:drawableRight="?android:attr/listChoiceIndicatorMultiple"` for a `CheckBox` and using the attributes `android:button="@null"` and `android:drawableRight="?android:attr/listChoiceIndicatorSingle"` for a `RadioButton`. But `android:button="@null"` seems to strip and widget tinting going on in an `AppCompat` theme for these widgets on Pre-Lollipop devices. – Etienne Lawlor Jan 16 '15 at 15:09
  • I see. They're indeed black. What I think is `AppCompat` recognizes `android:drawableRight` as _ordinary selector_ instead of _button-to-tint_. (If you remove `android:button="@null"` you can see original mark is properly tinted, but right one is still black). Anyway, the easiest workaround would be create custom compounds consisting of TextView and CheckBox/RadioButton without text. – paulina_glab Jan 17 '15 at 13:09
  • Is android:textColorSecondary used to style any other widgets beside the checkbox and radio button? – andrew Mar 31 '15 at 21:10
  • Yes, e.g. like right side of `SeekBar`'s bar. However, I can't guarantee, that support library would work as you want in each case - to be honest I don't think so:) [This color is also used to tint `Toolbar`'s icons, but for `Toolbar` we can provide theme, so it's easy to overwrite.] It seems to me, Google considered that it's not essential to change those colors (except accents), just leave them **consistent with main theme**. My problem was opposite: I set `android:textColorSecondary` (for Toolbar, before I create second theme), but I didn't want my widgets use it as their secondary color. – paulina_glab Apr 01 '15 at 08:15
  • This works for me on 5.0 and 5.1 but anything earlier still shows as black. My theme inherits from Theme.AppCompat. – Tunga Apr 15 '15 at 14:36
  • @Tunga, are you sure you set `name="colorAccent"`, not `name="android:colorAccent"`? You need to skip "android" namespace to benefit from support library feature. Also, support doesn't allow to give individual theme for single views (except Toolbar), so if theme you try to use is not the same as declared in `AndroidManifest.xml`, it will ignore that. – paulina_glab Apr 15 '15 at 15:57
  • Sorry, I should have been clearer, `colorAccent` works fine when the RadioButtons are selected, it's when they _not_ selected that they appear black (despite being on a dark theme). Basically `android:textColorSecondary` only seems to work on 5.x. All 4.x versions use the dark version regardless of the theme. I tried using just `textColorSecondary` as well but that doesn't work for _any_ version. – Tunga Apr 15 '15 at 16:10
  • For those seeing black on 4.x device, try to update to 22.1 appcompat. They seems to have fixed the tinting part, but I haven't tested it yet – Hrk Apr 23 '15 at 12:14
  • For me, I had to use `AppCompatRadioButton`, as `RadioButton` itself didn't work on pre-Lollipop devices. – Tim Cooke Jan 05 '16 at 05:25
  • @TimCooke This suggest you are using `Activity` base class other than [AppCompatActivity](http://developer.android.com/reference/android/support/v7/app/AppCompatActivity.html). See [here](http://android-developers.blogspot.com/2015/04/android-support-library-221.html). **AppCompat**->Paragraph 'The ability to tint...' shows that your problem is in ineffective usage of AppCompat, because this replacement should happen automatically. – paulina_glab Jan 05 '16 at 10:05
37

I believe this is an error in the AppCompat theme. My workaround adding two lines of code to each CheckBox in the xml layout file.

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

You never really want to direct reference abc_ drawables but in this case I found no other solution.

This applies to RadioButton widget as well! You would just use abc_btn_radio_material instead of abc_btn_check_material

Codeversed
  • 9,287
  • 3
  • 43
  • 42
18

I did this to change at least the border of a checkbox:

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

And in my layout

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

Still figuring out how to get the background of the checkbox though. Hope it helps.

Daniel S.
  • 730
  • 6
  • 14
  • This works for me. But one caveat is that AppCompatCheckBox does not seem to work on Android 5 and 6 (it just crashes). So you must use a regular CheckBox on these Android versions. – Mr-IDE Jan 19 '17 at 20:11
  • Great solution to change the theme of a single component instead of all components throughout the app (like the accepted answer). Also works for (my) situation with a regular CheckBox and `android:button="@null"` and `android:drawableRight="?android:attr/listChoiceIndicatorMultiple"`, which was also requested in some of the comments! – P Kuijpers Jul 20 '18 at 07:44
14

I had same problems as you. I looked once again at AppCompat v21 — Material Design for Pre-Lollipop Devices!

And I found this "All of your Activities must extend from ActionBarActivity, which extends from FragmentActivity from the v4 support library, so you can continue to use fragments.".

So I changed my activity to ActionBarActivity and it solved my problems. I hope it will solve yours too.

Tezi
  • 143
  • 1
  • 5
  • All my activities where already deriving from ActionBarActivity. I was upgrading the compat lib only, and found out that everything's perfect running the app on 5.0, but then realized it didn't perform as expected on any 4.x devices, checkboxes were barely visible, and completely invisible when I switch to a full black background instead of the default and ugly grey. – 3c71 Nov 28 '14 at 09:56
  • 1
    Another gotcha is that when inflating views for listviews, make sure the inflater is created from your ActionBarActivity, not from any other context (getBaseContext() included). So when creating your Adapters, remember to pass 'this' as the context. – Glenn.nz Mar 26 '15 at 22:04
  • 1
    This was the correct fix for me. Note that it appears that "ActionBarActivity" from the appcompat support library has been deprecated in favor of "AppCompatActivity". – TechnalyticSteve Jul 15 '15 at 23:35
8

I've been looking for a solution and I found it.

Step 1
Extend ActionBarActivity

public static class MyActivity extends ActionBarActivity {
        //...
}

Step 2
In your style file writes two values

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

colorAccent  - checked color
android:textColorSecondary - unchecked color

Step 3
Set your theme in 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>



RESULT
Android 5
android_5
Android 4.2.2
android_4.2.2

nexus700120
  • 81
  • 1
  • 2
7

1. Declare custom style in your styles.xml file.

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

2. Apply this style to your RadioButton via android:theme attribute.

  <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"/>
Muhamed Riyas M
  • 5,055
  • 3
  • 30
  • 31
  • Your parent theme will make it hard to see as it ends with `.Light`. If you remove the parent theme it will work on both light and dark themes of `AppCompat`. – blueware Mar 03 '19 at 15:57
7

100% Working

Just create a style for your RadioButton and change colorAccent like below:

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

Then simply add this style to your AppCompatRadioButton:

<android.support.v7.widget.AppCompatRadioButton
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:theme="@style/RadioButtonTeal" />
Amir Hossein Ghasemi
  • 20,623
  • 10
  • 57
  • 53
  • This seems to work. But you may find that AppCompatRadioButton causes crash on Android 5 and 6. So you must use a regular RadioButton on these Android versions. – Mr-IDE Jan 19 '17 at 20:13
4

To specify colors, override:

for checked color:

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

for unckecked color:

<item name="android:colorControlNormal">@color/your_color</item>
YTerle
  • 2,606
  • 6
  • 24
  • 40
3

You will get a lot of issues with the compatibility library with both check boxes and radio buttons.

1) They come only in black for any Android 4.x devices. They come ok in Android 5.x and 2.x (don't ask me why it works on 2.x, have no clue).

2) They don't have a disabled state (doesn't matter if all your checkboxes are enabled, otherwise you're good for a very bad surprise).

Note that the default dark theme background is grey, not black, so if you keep default it's "ok".

To solve this I created the white and a disabled version of the following drawables, all added to my core project, but not in the compat project (for obvious maintenance purpose):

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

Then created a drawable to manage all states (to override compat original state):

For example, the dark theme will use this:

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

The light theme will use this (user can switch theme in my app):

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

Then all I had to do is override the default compat theme (both activity and dialog, for both light/dark themes), adding something like this:

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

And this for light themes:

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

Now I've got fully operational check boxes and radios on every Android versions! IMO the compat library was not tested at all for dark theme, only white theme were used. Disabled state is likely never used by the dev of the compat lib either.

3c71
  • 4,313
  • 31
  • 43
  • But this doesn't work on AlertDialogs (Android 4.x) filled with setMultiChoiceItems(...)! They will be still the Holo-styled CheckBoxes... :( – silversmurf Dec 15 '14 at 12:38
  • Yes indeed. To work around that, you will need to replace the ListView 'on-the-fly', which I have done in my project, but it's another question and requires a very complicated 'hack' of the AlertDialog class. – 3c71 Feb 11 '15 at 13:27
  • Setting tint color seems to have been fixed in appcompat 22.1: http://developer.android.com/tools/support-library/index.html – Hrk Apr 23 '15 at 12:03
2

Just extend the ActionBarActivity like so:

Public class MainActivity extends ActionBarActivity {

//...

}
Leebeedev
  • 2,126
  • 22
  • 31
  • If you extend any of the standard views you have to extend the `TintXX` i.e. `TintCheckBox`. Alternative, if you don't want to extend `ActionBarActivity` you can just copy the `onCreateView` method from it. – pablisco Feb 03 '15 at 12:11
1

What you did should work for according to android blog post :

colorAccent : Bright complement to the primary branding color. By default, this is the color applied to framework controls (via colorControlActivated).

colorControlActivated : The color applied to framework controls in their activated (ex. checked) state.

Maybe the problem is coming from your theme that has @style/Theme.AppCompat.Light as parent, try with just Theme.AppCompat :

<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    <!-- customize the color palette -->
    <item name="colorAccent">@color/silver</item>
</style>
Gaëtan Maisse
  • 12,208
  • 9
  • 44
  • 47
  • Sorry forgot to mention, I've already tried `Theme.AppCompat`, didn't make any difference. – Nima Nov 10 '14 at 16:23
1

If you want to change a specific checkbox background color (not the whole app), you can try this trick:

Create custom_checkbox.xml file for background in drawable folder:

 <shape xmlns:android="http://schemas.android.com/apk/res/android">
     <stroke android:width="14dp" android:color="@android:color/transparent"  />
     <solid android:color="#ffffff" /> //the intended color of the background
     <corners android:radius="2dp" />
 </shape> 

and then set it as background of the checkbox:

<CheckBox
    android:id="@+id/rebate_tnc_checkbox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/custom_checkbox" />
Kharda
  • 1,318
  • 14
  • 23
1

you can pass another theme to the construct of the alert dialog

<style name="RadioButton" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="colorControlNormal">@color/red</item>
    <item name="colorControlActivated">@color/green</item>
</style>

and use that style in the constructor

new AlertDialog.Builder(getContext(), R.style.RadioButton);
SjoerdvGestel
  • 391
  • 2
  • 14
0

The parent of your AppTheme is @style/Theme.AppCompat.Light.

Change it to @style/Theme.AppCompat.

Now your controls will be light on a dark background.

Mark Buikema
  • 2,483
  • 30
  • 53
0

I am using appcompat library v21:

<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
        <item name="colorPrimary">@color/custom_color</item>
        <item name="colorAccent">@color/custom_color</item>    
</style>

The above style makes my checkbox to appear with material design (tested on android 5, 4.3, 4.1.1) but on android 2.3.3 appears with old checkbox style.

Kinga l
  • 71
  • 8
0

If you try to create ComboBox by hand (new ComboBox() ...), then no matter what you set, they are always going to be black. It is clear that the compat library is broken, I have created a bug report for this: https://code.google.com/p/android/issues/detail?id=158020

Martin Vysny
  • 3,088
  • 28
  • 39
0

add this syntax to color a widget like checkbox or radio button android:buttonTint="@color/silver"

Mayank Metha
  • 162
  • 13
0

Add

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

in style.xml and style.xml(v21)

touchchandra
  • 1,506
  • 5
  • 21
  • 37