AndroidJava動態修改CheckBox樣式

阿策~發表於2018-06-07

      小菜一直在處理動態配置頁面顏色方面的工作,包括各佈局,各控制元件等,而小菜卻在最常用最基本的 CheckBox 選項框這個控制元件卻栽了跟斗,折騰了好久,今天有機會總結整理一下。

      大家都很熟悉,xml 在很多時候大大節省了我們的開發時間,但 xml 裡面配置的樣式只有預設的,在動態修改方面還是要靠 Java/Kotlin 程式碼優化。基本上 xml 中可以配置的屬性在 Java/Kotlin 程式碼中都有相對應的方法,然而小菜在對應使用 CheckBox 控制元件的 **android:buttonTint=”@color/colorAccent”** 屬性時,卻不盡如人意,不僅在設定過程中需要版本大於21,更重要的是設定完之後並不起效果。小菜也查閱了不少資料,請教了幾位大神,依舊沒有解決問題。

      實在沒辦法,小菜決定放棄 CheckBox 轉投 v7 包中的 AppCompatCheckBox,通過設定 setSupportButtonTintList 方法來動態修改選項框顏色。

![測試效果圖.jpg](https://upload-images.jianshu.io/upload_images/6187924-3254c6a5eefc572a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

***

小菜的步驟如下:

1. 設定兩個預設的 CheckBox 選中/未選中 狀態作為參照,如圖中第一行;

2. 設定兩個 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>

“`

3. 設定兩個 AppCompatCheckBox 在 Java/Kotlin 程式碼中設定 setSupportButtonTintList 方法,但是在未選中狀態下,選擇框依舊是配置的主題色,與 CheckBox 預設的灰色不一致,如圖中第三行,仍需優化;

“`

accb.setSupportButtonTintList(ColorStateList.valueOf(getResources().getColor(R.color.colorAccent)));

“`

4. 設定兩個 AppCompatCheckBox 在 Java/Kotlin 程式碼中不僅設定 setSupportButtonTintList 方法,且監聽 CompoundButton.OnCheckedChangeListener 方法,再監聽選中和未選中狀態中對選項框顏色做處理。

“`Java

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 方法時,初始狀態為選中時,顏色列表第一個應為配置的顏色值;若為未選中時,顏色列表第一個應為預設系統灰色。

“`

// 工具類 繪製不同狀態的顏色

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;

    }

}

“`

“`

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

                }

            }

        });

    }

}

“`

“`

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

“`

***


相關文章