更改checkbox的值,而不触发onCheckChanged

我已经为我的checkbox实现了setOnCheckedChangeListener

有没有办法可以打电话

 checkbox.setChecked(false); 

而不会触发onCheckedChanged

不,你做不到。 onCheckedChanged方法直接从setChecked调用。 你可以做的是以下几点:

 mCheck.setOnCheckedChangeListener (null); mCheck.setChecked (false); mCheck.setOnCheckedChangeListener (mListener); 

查看CheckBox的来源 ,并执行setChecked

 public void setChecked(boolean checked) { if (mChecked != checked) { mChecked = checked; refreshDrawableState(); // 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); } mBroadcasting = false; } } 

你只需使用setonclickListener,它会正常工作,这是非常简单的方法,谢谢:)

另一种可能的方法是通过使用自定义CheckBox:

 public class CheckBox extends AppCompatCheckBox { private OnCheckedChangeListener mListener; public CheckBox(final Context context) { super(context); } public CheckBox(final Context context, final AttributeSet attrs) { super(context, attrs); } public CheckBox(final Context context, final AttributeSet attrs, final int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void setOnCheckedChangeListener(final OnCheckedChangeListener listener) { mListener = listener; super.setOnCheckedChangeListener(listener); } public void setChecked(final boolean checked, final boolean alsoNotify) { if (!alsoNotify) { super.setOnCheckedChangeListener(null); super.setChecked(checked); super.setOnCheckedChangeListener(mListener); return; } super.setChecked(checked); } public void toggle(boolean alsoNotify) { if (!alsoNotify) { super.setOnCheckedChangeListener(null); super.toggle(); super.setOnCheckedChangeListener(mListener); } super.toggle(); } } 

样本用法:

 checkBox.setChecked(true,false); 

您可以使用这个SafeCheckBox类作为您的checkbox:

 public class SafeCheckBox extends AppCompatCheckBox implements CompoundButton.OnCheckedChangeListener { private OnSafeCheckedListener onSafeCheckedListener; private int mIgnoreListener = CALL_LISTENER; public static final int IGNORE = 0; public static final int CALL_LISTENER = 1; @Retention(RetentionPolicy.SOURCE) @IntDef({IGNORE, CALL_LISTENER}) public @interface ListenerMode { } public SafeCheckBox(Context context) { super(context); init(context); } public SafeCheckBox(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public SafeCheckBox(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } /** * @param checkState change state of the checkbox to * @param mIgnoreListener true to ignore the listener else listener will be notified */ public void setSafeCheck(boolean checkState, @ListenerMode int mIgnoreListener) { if (isChecked() == checkState) return; //already in the same state no need to fire listener. if (onSafeCheckedListener != null) { // this to avoid a bug if the user listens for the event after using this method and in that case he will miss first check this.mIgnoreListener = mIgnoreListener; } else { this.mIgnoreListener = CALL_LISTENER; } setChecked(checkState); } private void init(Context context) { setOnCheckedChangeListener(this); } public OnSafeCheckedListener getOnSafeCheckedListener() { return onSafeCheckedListener; } public void setOnSafeCheckedListener(OnSafeCheckedListener onSafeCheckedListener) { this.onSafeCheckedListener = onSafeCheckedListener; } @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (onSafeCheckedListener != null) onSafeCheckedListener.onAlwaysCalledListener(buttonView, isChecked);// this has to be called before onCheckedChange if (onSafeCheckedListener != null && (mIgnoreListener == CALL_LISTENER)) { onSafeCheckedListener.onCheckedChanged(buttonView, isChecked); } mIgnoreListener = CALL_LISTENER; } /** * Listener that will be called when you want it to be called. * On checked change listeners are called even when the setElementChecked is called from code. :( */ public interface OnSafeCheckedListener extends OnCheckedChangeListener { void onAlwaysCalledListener(CompoundButton buttonView, boolean isChecked); } } 
  • 那么你可以打电话: –

    setSafeCheck(true,ListenerMode.IGNORE);// OnCheckedChange listener will not be notified

使用@Shade的Kotlin扩展回答:

 fun CompoundButton.setCustomChecked(value: Boolean,listener: CompoundButton.OnCheckedChangeListener) { setOnCheckedChangeListener(null) isChecked = value setOnCheckedChangeListener(listener) } 

我想用reflection是唯一的方法。 像这样的东西:

 CheckBox cb = (CheckBox) findViewById(R.id.checkBox1); try { Field field = CompoundButton.class.getDeclaredField("mChecked"); field.setAccessible(true); field.set(cb, cb.isChecked()); cb.refreshDrawableState(); cb.invalidate(); } catch (Exception e) { e.printStackTrace(); } 

对于任何人都会遇到这种情况,一个简单的方法就是在checkbox上使用一个标签,然后在其监听器上检查该标签(代码在Kotlin中):

 checkBox.tag = false checkBox.setOnCheckedChangeListener{ buttonView, isChecked -> if(checkBox.tag != true) { //Do some stuff } else { checkBox.tag = false } 

然后,在访问时只需将标记设置为true,然后在您要忽略值更改时将isChecked设置为true:

 checkBox.tag = true checkBox.isChecked = true 

如果您担心可以理解,您也可以使用替代setTag方法将标签映射到某个键。 但是,如果它的所有内容都包含在一个类中,那么一些注释string将足以解释发生了什么。

在检查单选button之前将null设置为changeListener。 检查单选button后,您可以再次设置监听器。

 radioGroup.setOnCheckedChangeListener(null); radioGroup.check(R.id.radioButton); radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) { } }); 

我的解决scheme写在基于@Chris的Java答案:

 chkParent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(buttonView.getTag() != null){ buttonView.setTag(null); return; } if(isChecked){ chkChild.setTag(true); chkChild.setChecked(false); } else{ chkParent.setChecked(true); } } }); chkChild.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(buttonView.getTag() != null){ buttonView.setTag(null); return; } if(isChecked){ chkParent.setTag(true); chkParent.setChecked(false); } else{ chkChild.setChecked(true); } } }); 

2checkbox,总是会有一个将被选中(一个必须首先检查)。 将标记设置为true可阻止onCheckedChanged侦听器。

我认为这是最简单的解释
可能会有所帮助)

 public class ProgrammableSwitchCompat extends SwitchCompat { public boolean isCheckedProgrammatically = false; public ProgrammableSwitchCompat(final Context context) { super(context); } public ProgrammableSwitchCompat(final Context context, final AttributeSet attrs) { super(context, attrs); } public ProgrammableSwitchCompat(final Context context, final AttributeSet attrs, final int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void setChecked(boolean checked) { isCheckedProgrammatically = false; super.setChecked(checked); } public void setCheckedProgrammatically(boolean checked) { isCheckedProgrammatically = true; super.setChecked(checked); } } 

用它

 @Override public void onCheckedChanged(CompoundButton compoundButton, boolean on) { if (((ProgrammableSwitchCompat) compoundButton).isCheckedProgrammatically) { return; } //... ((ProgrammableSwitchCompat) compoundButton).setCheckedProgrammatically(true); //... ((ProgrammableSwitchCompat) compoundButton).setCheckedProgrammatically(false); //... } 

使用会触发setChecked(boolean)函数
就这些

这是我使用的一个简单的解决scheme:
定义一个自定义侦听器:

 class CompoundButtonListener implements CompoundButton.OnCheckedChangeListener { boolean enabled = false; @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { } void enable() { enabled = true; } void disable() { enabled = false; } boolean isEnabled() { return enabled; } } 

初始化:

 CompoundButtonListener checkBoxListener = new CompoundButtonListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { if (isEnabled()) { // Your code goes here } } }; myCheckBox.setOnCheckedChangeListener(checkBoxListener); 

用法:

 checkBoxListener.disable(); // Some logic based on which you will modify CheckBox state // Example: myCheckBox.setChecked(true) checkBoxListener.enable();