android中使用多个CheckBox联动,CheckBox的setOnCheckedChangeListener和setOnClickListener使用
使用多个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); } } } }); }
以上是我的个人理解,如果有错误的地方,请帮忙指正,谢谢!
阅读更多
- (转)Android 中 CheckBox 的 setOnClickListener 和 setOnCheckedChangeListener 的不同之处在哪?
- Android开发中CheckBox的setOnClickListener和setOnCheckedChangeListener的不同之处在哪?
- Android开发中CheckBox、setOnClickListener和setOnCheckedChangeListener的不同之处在哪
- Android开发中CheckBox的setOnClickListener和setOnCheckedChangeListener的不同之处在哪?
- Android(5)多选按钮CheckBox、OnClickListener、OnCheckedChangeListener
- Expandablelistview与CheckBox+setOnCheckedChangeListener有坑
- Android APT开发教程 六 使用注解替代setOnClickListener还有注释
- CheckBox的OnCheckedChangeListener、OnClickListener、OnTouchListener
- 关于setOnCheckedChangeListener的使用
- CheckBox的OnCheckedChangeListener、OnClickListener、OnTouchListener
- 如何给checkbox创建setOnCheckedChangeListener()?
- Android APT开发教程 六 使用注解替代setOnClickListener还有注释给String赋值
- Android setOnClickListener使用方法
- Android中使用AlertDialog,使用函数setButton()出现的关于“new OnClickListener"错误
- <Android>setOnClickListener使用无效,报错null pointer
- Android CheckBox的OnCheckedChangeListener监听传值
- CheckBox的OnCheckedChangeListener、OnClickListener、OnTouchListener
- CheckBox的OnCheckedChangeListener、OnClickListener、OnTouchListener
- 关于Android setOnclicklistener抛出空指针的问题
- android setclickable()写在setonclickListener()前面会失效!