對於CheckBox的OnCheckedChangeListener,有兩種情況下會被觸發:
(1)用戶點擊了一下CheckBox;
(2)代碼中調用了setChecked(boolean checked)方法,而且參數checked與CheckBox原始的選中狀態不一致。
有時候,須要僅僅監聽(1)的事件。而忽略(2)的事件。
其實,這樣的需求十分常見。比如,頁面中有一個列表,列表中有多個checkBox供用戶選擇,同一時候頁面有一個全選功能的checkBox。
(a)當用戶將全選checkBox選上時。須要把列表中全部的checkBox都選上;
(b)當用戶將全選checkBox取消選擇時,須要把列表中全部的checkBox都選取消選擇。
(c)假設當前是全選狀態,僅僅要用戶隨意取消選擇了列表中一個checkBox,則將全選button取消選擇。
這時候問題就出現了:運行(c)時,須要對全選的checkBox.setChecked(false),而這會調用全選button的OnCheckedChangeListener。因為(b)的原因。列表中全部的checkBox都會被取消選擇,這不是期望的結果。
為了解決問題,有兩種方法:
方案(1):
程序中定義一個全局變量boolean ignoreChange,然后,調用setChecked方法時改變ignoreChange的值:
ignoreChange = true; selectAllCB.setChecked(true); ignoreChange = false;
然后在selectAllCB的OnCheckedChangeListener中對ignoreChange進行推斷:
selectAllCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (!ignoreChange) { //do something } } });方案(2):
對於checkBox不注冊OnCheckedChangeListener,而直接注冊OnClickListener,
checkBox.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { boolean checked = ((CheckBox) v).isChecked(); Toast.makeText(CheckBoxTest.this, "isChecked?" + checked, Toast.LENGTH_SHORT).show(); } });問題完美解決。