Android appcompat-v7:21.0.0 change material checkbox colors
Asked Answered
B

18

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.

Boice answered 10/11, 2014 at 11:44 Comment(5)
did you change styles in other Values folder like values-v14?Cathead
Which version of android you're check? Below API Level 14? or above?Detonation
@Arash No, I've deleted values-v14 etc. so this styles.xml is the only one.Boice
@HarshaVardhan above, testing on 4.4.2Boice
I think it was a bug in appcompat-lib. I faced the same issue with version 22.1.0. After updating to 22.1.1 widget tinting works again.Cease
F
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.

Forelock answered 10/11, 2014 at 18:42 Comment(12)
This doesn't work on Android 4.4.4 . The CheckBoxes and RadioButtons remain black.Personally
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.Forelock
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.Personally
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.Forelock
Is android:textColorSecondary used to style any other widgets beside the checkbox and radio button?Pulverulent
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.Forelock
This works for me on 5.0 and 5.1 but anything earlier still shows as black. My theme inherits from Theme.AppCompat.Schwann
@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.Forelock
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.Schwann
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 yetEllie
For me, I had to use AppCompatRadioButton, as RadioButton itself didn't work on pre-Lollipop devices.Soothsayer
@TimCooke This suggest you are using Activity base class other than AppCompatActivity. See here. AppCompat->Paragraph 'The ability to tint...' shows that your problem is in ineffective usage of AppCompat, because this replacement should happen automatically.Forelock
N
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

Nertie answered 16/1, 2015 at 16:5 Comment(4)
Fantastic! Using the Tint and setting it to primary color properly themed the UI :-)Gamma
This will not change ripple effect color.Sulk
@Sulk I will have to test again... could be sdk specific.Nertie
@Waza_Be, if you want to change ripple effect color, put this item in your main app theme: <item name="colorControlHighlight">@color/yourRippleColor</item>Brucite
A
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.

Amphitryon answered 27/4, 2016 at 20:43 Comment(2)
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.Alfy
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!Nacreous
O
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.

Oribel answered 15/11, 2014 at 16:42 Comment(3)
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.Bainter
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.Compulsory
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".Kaif
E
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

Eloiseloisa answered 17/2, 2015 at 7:42 Comment(1)
This didn't help me. I had to add app:buttonTint="?attr/colorAccent" to each RadioButton/CheckBox.Arytenoid
C
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"/>
Cognizable answered 27/1, 2016 at 12:58 Comment(1)
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.Brucite
S
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" />
Skinflint answered 27/1, 2016 at 17:39 Comment(1)
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.Alfy
E
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>
Etalon answered 13/4, 2016 at 8:27 Comment(0)
B
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.

Bainter answered 28/11, 2014 at 9:37 Comment(3)
But this doesn't work on AlertDialogs (Android 4.x) filled with setMultiChoiceItems(...)! They will be still the Holo-styled CheckBoxes... :(Bak
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.Bainter
Setting tint color seems to have been fixed in appcompat 22.1: developer.android.com/tools/support-library/index.htmlEllie
G
2

Just extend the ActionBarActivity like so:

Public class MainActivity extends ActionBarActivity {

//...

}
Gingham answered 16/12, 2014 at 19:53 Comment(1)
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.Clostridium
F
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>
Flight answered 10/11, 2014 at 16:3 Comment(1)
Sorry forgot to mention, I've already tried Theme.AppCompat, didn't make any difference.Boice
U
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" />
Uraemia answered 4/1, 2016 at 3:31 Comment(0)
R
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);
Raul answered 26/8, 2016 at 12:3 Comment(0)
D
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.

Duplicate answered 11/1, 2015 at 17:8 Comment(0)
K
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.

Kraus answered 12/1, 2015 at 14:25 Comment(0)
U
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

Uniform answered 2/3, 2015 at 21:19 Comment(0)
T
0

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

Tattered answered 1/7, 2015 at 11:5 Comment(0)
P
0

Add

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

in style.xml and style.xml(v21)

Provence answered 1/8, 2015 at 1:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.