Tinting Checkbox on pre v21
Asked Answered
C

5

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?

Conant answered 23/10, 2014 at 15:47 Comment(0)
H
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"/>
Hyperboloid answered 15/1, 2016 at 13:24 Comment(4)
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.Tannenberg
you deserve a medal !Dupion
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!Hindsight
May those for who it doesn't work are trying a custom image, for that this does NOT work.Titania
S
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" />
Salzburg answered 31/3, 2016 at 1:35 Comment(2)
Thanks a lot for the answer :)Guv
It doesn't work. I've checked it. + AppCompat* widgets are applied automatically if they're not dynamically created.Fender
R
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));
}
Rigdon answered 20/2, 2016 at 20:54 Comment(6)
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);'.Entourage
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));'Rigdon
@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?Rigdon
in the meantime I reverted the code to my original answerRigdon
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.Rigdon
With new support library you should use: CompoundButtonCompat.setButtonTintList(_checkbox, new ColorStateList(states, colors));Attar
F
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>
Fleecy answered 30/1, 2017 at 22:29 Comment(0)
M
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()).
Megaron answered 23/10, 2014 at 16:56 Comment(3)
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.Conant
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.Megaron
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 :(Hyperboloid

© 2022 - 2024 — McMap. All rights reserved.