在 Android 中使用颜色选择器设置复选框颜色

Set checkbox color with a color selector in Android

我正在我的 android 应用程序中为 Checkbox 设置 属性 buttonTint,并使用颜色选择器使其在 checked/unchecked 时改变颜色].

这是我的 XML 复选框样式:

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

这是我的 XML 选择器:

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

但它无法正常工作。当 Checkbox 一开始可见时(灰色),它的颜色是正确的。当 clicked/checked 时,它会变成绿色。但是当它再次取消选中时,由于某种原因它仍然是绿色的。

编辑

问题也可能是我在清单中选择的主题引起的。我正在使用这个自定义主题:

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

尝试以下代码:以编程方式更改 checkbox 按钮背景

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() 已弃用,您需要使用 ContextCompat.getColor(context, R.color.color)

第二种方式

使用您的颜色集创建一个颜色列表变量

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
        }
);

设置颜色使用:setButtonTintList()

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

我遇到了和你一样的问题,突然灵机一动。为什么不使用选择器。所以我自己试了一下,成功了。

解法:

在 res 文件夹下创建 color 文件夹,如果你没有并放置这个颜色选择器

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>

在你的复选框内:

app:buttonTint="@color/checkbox_selector"

我根据 rafsanahmad007 发布的一些代码找到了解决方案。我创建了一个带有侦听器的自定义复选框视图,根据其自身状态(选中或未选中)更改色调。

我的自定义视图代码:

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);
        }
    }
}