How to Change The Checked Tint Color of a CheckedTextView with Hex Value

2.5k Views Asked by At

I want to dynamically change the tint color of a CheckedTextView when the state of the view is checked. I am pretty sure I can achieve this by calling setCheckMarkTintList on the CheckedTextView. To do this, I need a ColorStateList, but the problem is I want to retain all of the colors for each state of the CheckedTextView, except for the checked state.

So, I can obtain the ColorStateList of the CheckedTextView, but I do not know of a way to change only the color for the checked state. I know I can create a new ColorStateList, but how do I make sure it retains all of the values from the original?

I can create a state list like this:

int[][] states = new int[][] {
    new int[]{android.R.attr.state_pressed},
    new int[]{-android.R.attr.state_pressed},
    new int[]{android.R.attr.state_focused},
    new int[]{-android.R.attr.state_focused},
    new int[]{android.R.attr.state_selected},
    new int[]{-android.R.attr.state_selected},
    new int[]{android.R.attr.state_checkable},
    new int[]{-android.R.attr.state_checkable},
    new int[]{android.R.attr.state_checked},
    new int[]{-android.R.attr.state_checked},
    new int[]{android.R.attr.state_enabled},
    new int[]{-android.R.attr.state_enabled},
    new int[]{android.R.attr.state_window_focused},
    new int[]{-android.R.attr.state_window_focused},
    new int[]{} // default state
}

And create a color list from the colors from the original ColorStateList:

int[] colors = new int[] {
    stateList.getColorForState(new int[]{android.R.attr.state_pressed}, stateList.getDefaultColor()),
    stateList.getColorForState(new int[]{-android.R.attr.state_pressed}, stateList.getDefaultColor()),
    stateList.getColorForState(new int[]{android.R.attr.state_focused}, stateList.getDefaultColor()),
    stateList.getColorForState(new int[]{-android.R.attr.state_focused}, stateList.getDefaultColor()),
    stateList.getColorForState(new int[]{android.R.attr.state_selected}, stateList.getDefaultColor()),
    stateList.getColorForState(new int[]{-android.R.attr.state_selected}, stateList.getDefaultColor()),
    stateList.getColorForState(new int[]{android.R.attr.state_checkable}, stateList.getDefaultColor()),
    stateList.getColorForState(new int[]{-android.R.attr.state_checkable}, stateList.getDefaultColor()),
    Color.parseColor(colorHexValue),
    stateList.getColorForState(new int[]{-android.R.attr.state_checked}, stateList.getDefaultColor()),
    stateList.getColorForState(new int[]{android.R.attr.state_enabled}, stateList.getDefaultColor()),
    stateList.getColorForState(new int[]{-android.R.attr.state_enabled}, stateList.getDefaultColor()),
    stateList.getColorForState(new int[]{android.R.attr.state_window_focused}, stateList.getDefaultColor()),
    stateList.getColorForState(new int[]{-android.R.attr.state_window_focused}, stateList.getDefaultColor()),
    stateList.getDefaultColor()
}

But this would only cover the solitary states... you can also combine states, such as new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed, -android.R.attr.state_checked}. It would be ridiculous to try to account for every possible state, so how can I possibly know what states the original ColorStateList has set? Is there an easier way of doing this? Am I overthinking it?

3

There are 3 best solutions below

0
On

This changes the CheckedTextView color from green to whatever color you specify

android:drawableTint="@color/grey_text"

0
On

it looks like tinting in a CheckedTextView is pretty buggy. At the end I solved it by swapping colors in onClickListener:

checkedTextView.setOnClickListener {
    if (checkedTextView.isChecked) {
        checkedTextView.checkMarkTintList = ColorStateList.valueOf(color1)
    } else {
        checkedTextView.checkMarkTintList = ColorStateList.valueOf(color2)
    }
}

(example in Kotlin, Java is similar)

0
On

if you need to change it programmatically, you can set a ColorStateList like this:

                int[] colors = new int[] {
                        color,
                        color,
                        color,
                        color
                };

                int[][] states = new int[][] {
                        new int[] { android.R.attr.state_enabled}, // enabled
                        new int[] {-android.R.attr.state_enabled}, // disabled
                        new int[] {-android.R.attr.state_checked}, // unchecked
                        new int[] { android.R.attr.state_pressed}  // pressed
                };

                ColorStateList myList = new ColorStateList(states, colors);
                checkedTextView.setCheckMarkTintList(myList);