您的位置:首页 > 移动开发 > Android开发

android中使用多个CheckBox联动,CheckBox的setOnCheckedChangeListener和setOnClickListener使用

2018-11-04 00:04 1011 查看

使用多个CheckBox进行联动时,应该使用setOnClickListener替代OnCheckedChangeListener

以下是错误代码(正确代码在文末):

[code]private void initCheckBox(final List<CheckBox> checkBoxList, final CheckBox checkBoxAll) {
// 初始化 各个 子的 ChechBox
for (CheckBox checkBox : checkBoxList) {
checkBox.setOnCheckedChangeListener(newCompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
boolean isAllSelect = true; // 假设全部都已经被选中了
for (CheckBox checkBox : checkBoxList) { // checkBoxList_First
if (!checkBox.isChecked()) { // 只要有一个没被选中 ,就说明不是全部被选中,如果遍历完之后还没有找到,那么就设置为true
isAllSelect = false;
break;
}
}
checkBoxAll.setChecked(isAllSelect);
}
});
}

checkBoxAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
for (CheckBox checkBox : checkBoxList) {
checkBox.setChecked(true);
}
} else {

for (CheckBox checkBox : checkBoxList) {
checkBox.setChecked(false);
}
}
}
});

}

这样的代码,乍一看,感觉没什么毛病,不过就是点击全选的时候,则所有的子CheckBox都选中;当所有的子CheckBox都选中时,checkBoxAll选中状态为true,否则,checkBoxAll选中状态为false。但是运行在项目的时候,会发现,当所有的子CheckBox都选中了,虽然此时,checkBoxAll也显示为选中状态,但是当对其中一个子CheckBox取消选中时,所有的子CheckBox都被取消选中了。

经过查看CheckBox的源码,发现,当CheckBox执行setChecked时,会触发执行OnCheckedChangeListener,所以,当所有的子CheckBox都选中后取消其中一个,会执行checkBoxAll.setChecked(false),而此时,会执行checkBoxAll的OnCheckedChangeListener,执行后,则将所有的子CheckBox都变成了取消状态。

[code]    public void setChecked(boolean checked) {
if (mChecked != checked) {
mCheckedFromResource = false;
mChecked = checked;
refreshDrawableState();
notifyViewAccessibilityStateChangedIfNeeded(
AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);

// Avoid infinite recursions if setChecked() is called from a listener
if (mBroadcasting) {
return;
}

mBroadcasting = true;
if (mOnCheckedChangeListener != null) {
mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
}
if (mOnCheckedChangeWidgetListener != null) {
mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
}
final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
if (afm != null) {
afm.notifyValueChanged(this);
}

mBroadcasting = false;
}
}

这里,考虑使用setOnClickListener来替代setOnCheckedChangeListener,因为setCheck虽然会触发OnCheckedChangeListener,但是不会触发OnClickListener。

所以将checkBoxAll的初始化代码改为以下代码:

[code]  checkBoxAll.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!checkBoxAll.isChecked()) { // 未选中时,则选中
checkBoxAll.setChecked(true);
for (CheckBox checkBox : checkBoxList) {
checkBox.setChecked(true);
}
} else { // 选中时,则设置为未选中
checkBoxAll.setChecked(false);
for (CheckBox checkBox : checkBoxList) {
checkBox.setChecked(false);
}
}
}
});

这样,看起来也一样没毛病,完全符合逻辑。但是,当点击checkBoxAll时,会出现checkBoxAll的选中状态一闪而过。

但是,经验证,当CheckBox被点击的时候,setOnCheckedChangeListener会比setOnClickListener先执行,即当手指点击的时候,此时,若原本checkBoxAll是true状态,先执行了setOnCheckedChangeListener,则变成false,而setOnClickListener中的代码后执行,又被设置为true,所以就出现了一闪而过的现象。

   

好了,说了这么多,最终代码应该为(子CheckBox的OnCheckedChangeListener也可以使用setOnClickListener去处理):

[code] private void initCheckBox(final List<CheckBox> checkBoxList, final CheckBox checkBoxAll) {
// 初始化 各个 子的 ChechBox
for (CheckBox checkBox : checkBoxList) {

checkBox.setOnCheckedChangeListener(newCompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
boolean isAllSelect = true; // 假设全部都已经被选中了
for (CheckBox checkBox : checkBoxList) {
if (!checkBox.isChecked()) { // 只要有一个没被选中 ,就说明 不是全部被选中,如果遍历完之后还没有找到,那么就设置为true
isAllSelect = false;
break;
}
}
checkBoxAll.setChecked(isAllSelect);
}
});
}

checkBoxAll.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

if (checkBoxAll.isChecked()) {
checkBoxAll.setChecked(true);
for (CheckBox checkBox : checkBoxList) {
checkBox.setChecked(true);
}
} else {
checkBoxAll.setChecked(false);
for (CheckBox checkBox : checkBoxList) {
checkBox.setChecked(false);
}
}
}
});
}

以上是我的个人理解,如果有错误的地方,请帮忙指正,谢谢!

 

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: