Langkiller
Langkiller

Reputation: 3457

Set checkbox color with a color selector in Android

I am setting the property buttonTint for a Checkbox in my android app with a color selector to make it change color when it is checked/unchecked.

Here is my XML for the checkbox style:

<style name="standard_checkbox">
    <item name="android:layout_marginLeft">@dimen/checkbox_small_margin</item>
    <item name="android:layout_marginRight">@dimen/checkbox_small_margin</item>
    <item name="buttonTint">@color/checkbox_standard_selector</item>
</style>

And here is my XML for the selector:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:color="@color/checkbox_checked" />
    <item android:state_checked="false" android:color="@color/checkbox_unchecked" />
</selector>

But it isn't working properly. The Checkbox has the correct color when it becomes visible at first (grey). When clicked/checked, it becomes green like it should. But when it is unchecked again, it remains green for some reason.

Edit

The problem may also be caused by my choice of theme in the manifest. I am using this customized theme:

<style name="Theme.Transparent.NoActionBar" parent="Theme.AppCompat.NoActionBar">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>

Upvotes: 2

Views: 2994

Answers (3)

Langkiller
Langkiller

Reputation: 3457

I found a solution, based on some of the code posted by rafsanahmad007. I have created a custom checkbox view with a listener, changing the tint color based on its own state (checked or not).

Code for my custom view:

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.CompoundButtonCompat;
import android.util.AttributeSet;
import android.widget.CheckBox;
import android.widget.CompoundButton;

public class CustomCheckBox extends CheckBox implements CompoundButton.OnCheckedChangeListener {

    private OnCheckedChangeListener listener;
    private int currentColor;

    public CustomCheckBox(Context context, AttributeSet attrs) {
        super(context, attrs);
        super.setOnCheckedChangeListener(this);
        setCheckboxColor();
    }

    private void setCheckboxColor() {
        ColorStateList colorStateList = new ColorStateList(
                new int[][]{
                        new int[]{android.R.attr.state_enabled},
                },
                new int[]{
                        getCurrentColor()
                }
        );
        CompoundButtonCompat.setButtonTintList(this, colorStateList);
    }

    @Override
    public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
        this.listener = listener;
    }

    public int getCurrentColor() {
        if (isChecked()) {
            return ContextCompat.getColor(getContext(), R.color.checkbox_checked);
        } else {
            return ContextCompat.getColor(getContext(), R.color.checkbox_unchecked);
        }
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        setCheckboxColor();
        if (listener != null) {
            listener.onCheckedChanged(buttonView, isChecked);
        }
    }
}

Upvotes: 1

rafsanahmad007
rafsanahmad007

Reputation: 23881

try the following code: to programetically change checkbox button background

CheckBox cb = (CheckBox) findViewById(R.id.checkbox);
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) { 
            buttonView.setBackgroundColor(getResources().getColor(R.color.checked));
            }
        if (!isChecked) { 
            buttonView.setBackgroundColor(getResources().getColor(R.color.unchecked)); 
            }
    }
});

N.B: getColor() is deprecated u need to use ContextCompat.getColor(context, R.color.color)

Second Way

create a colorlist variable with your color's set

ColorStateList  colorStateList = new ColorStateList(
        new int[][]{
                new int[]{-android.R.attr.state_checked}, // unchecked
                new int[]{android.R.attr.state_checked} , // checked
        },
        new int[]{
                Color.parseColor("#FFFFFF"),  //unchecked color
                Color.parseColor("#009000"),  //checked color
        }
);

set the color using: setButtonTintList()

 CheckBox cb = (CheckBox) findViewById(R.id.checkbox);
 CompoundButtonCompat.setButtonTintList(cb,colorStateList);

Upvotes: 3

Vygintas B
Vygintas B

Reputation: 1694

I had same problem as you and suddenly got idea. Why not to use selector. So I tried myself and it worked.

Solution:

Under res folder create color folder if you don't have one and put this color selector

checkbox_selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_checked="true" android:color="@color/colorPrimary" />
   <item android:state_checked="false" android:color="@color/colorSecondary" />
</selector>

And inside your checkbox:

app:buttonTint="@color/checkbox_selector"

Upvotes: 3

Related Questions