24

So, I want to apply tint to AppCompat Checkbox.

Everything works fine on Lollipop:

android:buttonTint="@color/purple_FF4081"

or this way:

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

But setting any of this params do not change anything on pre-Lollipop. Works only if I set colorAccent for the app theme. But I don't want all widgets to change their look, just one checkbox. Is there any way to do this without setting colored drawables?

bluebyte
  • 560
  • 2
  • 7
  • 23

5 Answers5

64

Quick fyi that this has all changed now after the introduction of the AppCompatActivity and the new support libraries, for reference (outlined beautifully here) a checkbox can be tinted by using the theme atttribute and setting the colorControlNormal and colorControlActivated:

styles.xml

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

layout xml:

<CheckBox  
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="true"
        android:text="Check Box"
        android:theme="@style/MyCheckBox"/>
Daniel Wilson
  • 18,838
  • 12
  • 85
  • 135
  • This is gold ! Was looking for this answer. By the way, what is the default color of the checkbox? If I would like to have the the normal state to be the default color, what would that be? I tried "@null" but that did not work. – Red M May 02 '17 at 00:04
  • you deserve a medal ! – Sadiq Md Asif Aug 03 '17 at 15:00
  • Not sure this should be the answer as I'm getting a warning this requires API 21 whereas the question specifically states *pre* 21. Unless I'm doing something wrong that is! – Mark A. Donohoe Aug 14 '17 at 19:12
  • May those for who it doesn't work are trying a custom image, for that this does NOT work. – Kenny Jan 17 '18 at 15:37
25

You can color directly in the xml. Use buttonTint for the box: (as of API level 23)

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

You can also do this using appCompatCheckbox v7 for older APIs:

<android.support.v7.widget.AppCompatCheckBox 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    app:buttonTint="@color/COLOR_HERE" />
Anudeep Samaiya
  • 1,910
  • 2
  • 28
  • 33
11

I needed to do it programmatically, after digging for a little while I finally found this solution (tested on Kitkat & Marshmallow), I'll just post it in case it helps someone:

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));
}
androidseb
  • 1,257
  • 2
  • 14
  • 17
  • Did not work for me. No matter what color I provided it is always gray for both checked and unchecked states. I called the function as follows: 'setAppCompatCheckBoxColors(checkBox, R.color.simple_red, R.color.colorPrimary);' where I created the checkbox using 'AppCompatCheckBox checkBox = new AppCompatCheckBox(context);'. – Zvi Jul 16 '16 at 17:51
  • 2
    You're using color res ids, you should specify the color itself, like this: 'setAppCompatCheckBoxColors(checkBox, Color.YELLOW, Color.RED);' or like this in your instance: 'setAppCompatCheckBoxColors(checkBox, activity.getResources().getColor(R.color.simple_red), activity.getResources().getColor(R.color.colorPrimary));' – androidseb Jul 18 '16 at 16:06
  • @jzeferino: you edited my answer and changed "int[][] states = new int[][]{new int[]{-android.R.attr.state_checked}, new int[]{android.R.attr.state_checked}};" to "int[][] states = new int[][]{new int[]{android.R.attr.state_checked}, new int[]{android.R.attr.state_checked}};". This change seems to make the code not work anymore, could you explain the change please? – androidseb Aug 22 '16 at 16:38
  • in the meantime I reverted the code to my original answer – androidseb Aug 22 '16 at 16:40
  • and with the "-" removed, calling say setAppCompatCheckBoxColors(checkBox, Color.YELLOW, Color.GREEN) successfully colors the checkbox in yellow when unchecked and in green when checked? I tested with your modification and the unchecked state would not render at all, the checkbox would become invisible when unchecked. – androidseb Aug 22 '16 at 16:46
  • 3
    With new support library you should use: CompoundButtonCompat.setButtonTintList(_checkbox, new ColorStateList(states, colors)); – Patrick Boos Mar 28 '17 at 23:14
2

I have tried all answer but only this one works for me , add atttribute colorControlNormal and colorControlActivated to base style of whole activity (or application ) remove theme from your controller

here is example

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

Your Mainfest

<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>
Mina Fawzy
  • 20,852
  • 17
  • 133
  • 156
1

EDIT 6/28/16: The below answer is no longer correct. See the accepted answer on the new way Google has allowed tinting on pre-v21 devices with the appcompat library.


Original Answer:

The short answer is: no. Custom drawables will need to be created for use on pre-v21 devices. This is because the special tint aware widgets are currently hidden because they're an unfinished implementation detail at this time (which Google states that this may change in the future, according to their developer blog in the FAQ section)

There are two scenarios you could override the colorAccent that may work:

  • Have your own custom version of the widget (i.e. you’ve extended EditText)
  • Creating the EditText without a LayoutInflater (i.e., calling new EditText()).
opt05
  • 813
  • 11
  • 21
  • 2
    I see that google says in **widget tinting**: You don’t need to do anything special to make these work, just use these controls in your layouts as usual and AppCompat will do the rest. – bluebyte Oct 24 '14 at 07:21
  • Yes, Android will override the color scheme with AppCompat if you define the colorAccent in your app style.xml. But as I said, currently it is an all or nothing with the current AppCompat. – opt05 Oct 27 '14 at 19:50
  • It's a shame, they've added the ability to set the theme on any view now (so for example you could invert the theme of the checkbox to work on an opposite color), but it doesn't seem to work in the app compat library. Plus you can set the button tinit but that only works in 21+ as well :( – Daniel Wilson Feb 28 '15 at 22:50