和尚我一直在处理动态配置页面颜色方面的工作,包括各布局,各控件等,而和尚我却在最常用最基本的 CheckBox 选项框这个控件却栽了跟头,折腾了好久,今天有机会总结整理一下。 大家都很熟悉,xml 在很多时候大大节省了我们开发的时间,但 xml 里面配置的样式只有默认的,在动态修改方面还是要靠 Java/Kotlin 代码优化。基本上 xml 中可以配置的属性在 Java/Kotlin 代码中都有相对应的方法,然而和尚我在对应使用 CheckBox 控件的 android:buttonTint="@color/colorAccent" 属性时,却不尽如人意,不仅在设置过程中需要版本大于21,更重要的是设置完之后并不起效果。和尚我也查阅了不少资料,请教了几位大神,依旧没有解决问题。 实在没办法,和尚我决定放弃 CheckBox 转投 v7 包中的 AppCompatCheckBox,通过设置 setSupportButtonTintList 方法来动态修改选项框颜色。
和尚我的步骤如下:
- 设置两个默认的 CheckBox 选中/未选中 状态作为参照,如图中第一行;
- 设置两个 AppCompatCheckBox 默认通过设置 style.xml 主题色配置,可实现与 CheckBox 效果一致,如图中第二行,但并非和尚我想要的方式;
<style name="MyCheckBox" parent="Theme.AppCompat.Light">
<item name="colorControlNormal">@color/avoscloud_feedback_text_gray</item>
<item name="colorControlActivated">@color/colorPrimary</item>
</style>
<style name="MyCheckBox2" parent="Theme.AppCompat.Light">
<item name="colorControlNormal">@color/avoscloud_feedback_text_gray</item>
<item name="colorControlActivated">@color/colorPrimaryDark</item>
</style>
- 设置两个 AppCompatCheckBox 在 Java/Kotlin 代码中设置 setSupportButtonTintList 方法,但是在未选中状态下,选择框依旧是配置的主题色,与 CheckBox 默认的灰色不一致,如图中第三行,仍需优化;
accb.setSupportButtonTintList(ColorStateList.valueOf(getResources().getColor(R.color.colorAccent)));
- 设置两个 AppCompatCheckBox 在 Java/Kotlin 代码中不仅设置 setSupportButtonTintList 方法,且监听 CompoundButton.OnCheckedChangeListener 方法,再监听选中和未选中状态中对选项框颜色做处理。
accb.setSupportButtonTintList(BitmapUtil.createColorStateList(Color.GRAY, Color.RED, Color.RED,Color.RED));
accb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b)
{
if(b){
accb.setSupportButtonTintList(BitmapUtil.createColorStateList(Color.RED, Color.RED, Color.RED,Color.RED));
}else{
accb.setSupportButtonTintList(BitmapUtil.createColorStateList(Color.GRAY, Color.RED, Color.RED,Color.RED));
}
}
});
Tips1: 若 Java/Kotlin 代码与 style.xml 均设置样式,以 Java/Kotlin 代码样式为主。 Tips2: 在设置 setSupportButtonTintList 方法时,初始状态为选中时,颜色列表第一个应为配置的颜色值;若为未选中时,颜色列表第一个应为默认系统灰色。
代码语言:javascript复制// 工具类 绘制不同状态的颜色
public class BitmapUtil {
/**
* 对TextView设置不同状态时其文字颜色
* @param normal
* @param pressed
* @param focused
* @param unable
* @return
*/
public static ColorStateList createColorStateList(int normal, int pressed, int focused, int unable) {
int[] colors = new int[] { pressed, focused, normal, focused, unable, normal };
int[][] states = new int[6][];
states[0] = new int[] { android.R.attr.state_pressed, android.R.attr.state_enabled };
states[1] = new int[] { android.R.attr.state_enabled, android.R.attr.state_focused };
states[2] = new int[] { android.R.attr.state_enabled };
states[3] = new int[] { android.R.attr.state_focused };
states[4] = new int[] { android.R.attr.state_window_focused };
states[5] = new int[] {};
ColorStateList colorList = new ColorStateList(states, colors);
return colorList;
}
}
代码语言:javascript复制// Java 对 AppCompatCheckBox 绘制颜色
public class CheckBoxActivity extends AppCompatActivity {
AppCompatCheckBox accb1, accb2, accb3, accb4, accb5, accb6;
TextView mTitleTv;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_checkbox);
mTitleTv = (TextView) this.findViewById(R.id.tv_toolbar_title);
mTitleTv.setText("Java 动态修改 CheckBox 颜色");
accb1 = (AppCompatCheckBox) this.findViewById(R.id.accb1);
accb2 = (AppCompatCheckBox) this.findViewById(R.id.accb2);
accb3 = (AppCompatCheckBox) this.findViewById(R.id.accb3);
accb4 = (AppCompatCheckBox) this.findViewById(R.id.accb4);
accb5 = (AppCompatCheckBox) this.findViewById(R.id.accb5);
accb6 = (AppCompatCheckBox) this.findViewById(R.id.accb6);
accb3.setSupportButtonTintList(ColorStateList.valueOf(getResources().getColor(R.color.colorAccent)));
accb4.setSupportButtonTintList(ColorStateList.valueOf(Color.GREEN));
accb5.setSupportButtonTintList(BitmapUtil.createColorStateList(getResources().getColor(R.color.colorAccent), getResources().getColor(R.color.colorAccent), getResources().getColor(R.color.colorAccent), getResources().getColor(R.color.colorAccent)));
accb5.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
accb5.setSupportButtonTintList(BitmapUtil.createColorStateList(getResources().getColor(R.color.colorAccent), getResources().getColor(R.color.colorAccent), getResources().getColor(R.color.colorAccent), getResources().getColor(R.color.colorAccent)));
} else {
accb5.setSupportButtonTintList(BitmapUtil.createColorStateList(Color.GRAY, getResources().getColor(R.color.colorAccent), getResources().getColor(R.color.colorAccent), getResources().getColor(R.color.colorAccent)));
}
}
});
accb6.setSupportButtonTintList(BitmapUtil.createColorStateList(Color.GRAY, Color.GREEN, Color.GREEN, Color.GREEN));
accb6.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
accb6.setSupportButtonTintList(BitmapUtil.createColorStateList(Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN));
} else {
accb6.setSupportButtonTintList(BitmapUtil.createColorStateList(Color.GRAY, Color.GREEN, Color.GREEN, Color.GREEN));
}
}
});
}
}
代码语言:javascript复制// xml 布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/common_title" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="12dp"
android:paddingTop="12dp"
android:text="系统默认 CheckBox"
android:textColor="@color/colorAccent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="12dp">
<CheckBox
android:id="@ id/cb1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:checked="true"
android:text="默认已选中" />
<CheckBox
android:id="@ id/cb2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="false"
android:text="默认未选中" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="12dp"
android:paddingTop="12dp"
android:text="AppCompatCheckBox style.xml 主题色配置"
android:textColor="@color/colorPrimary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="12dp">
<android.support.v7.widget.AppCompatCheckBox
android:id="@ id/accb1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:checked="true"
android:text="默认已选中"
android:theme="@style/MyCheckBox" />
<android.support.v7.widget.AppCompatCheckBox
android:id="@ id/accb2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:checked="false"
android:text="默认未选中"
android:theme="@style/MyCheckBox2" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="12dp"
android:paddingTop="12dp"
android:text="AppCompatCheckBox Java 代码颜色配置"
android:textColor="@color/colorAccent" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="12dp"
android:paddingTop="12dp"
android:text="但未选中状态中与系统灰色不一致,需修改" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="12dp">
<android.support.v7.widget.AppCompatCheckBox
android:id="@ id/accb3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:checked="true"
android:text="默认已选中"
android:theme="@style/MyCheckBox" />
<android.support.v7.widget.AppCompatCheckBox
android:id="@ id/accb4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:checked="false"
android:text="默认未选中"
android:theme="@style/MyCheckBox" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="12dp"
android:paddingTop="12dp"
android:text="与系统默认的 CheckBox 样式基本一致" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="12dp">
<android.support.v7.widget.AppCompatCheckBox
android:id="@ id/accb5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:checked="true"
android:text="默认已选中" />
<android.support.v7.widget.AppCompatCheckBox
android:id="@ id/accb6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:checked="false"
android:text="默认未选中" />
</LinearLayout>
</LinearLayout>