15 ответов:
нет, вы не можете сделать это. Элемент
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; } }
еще один возможный способ добиться этого-использовать пользовательский флажок:
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);
вы используете просто setonclickListener, он будет отлично работать, и это очень простой метод, спасибо:)
вы можете использовать этот класс SafeCheckBox в качестве флажка:
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 ответ:
fun CompoundButton.setCustomChecked(value: Boolean,listener: CompoundButton.OnCheckedChangeListener) { setOnCheckedChangeListener(null) isChecked = value setOnCheckedChangeListener(listener) }
для тех, кто натыкается на это, один простой способ сделать это-просто использовать тег на флажке, а затем проверить этот тег на своем слушателе (код находится в Котлине):
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, который требует ключа, если вы беспокоились о понятности. Но если его все содержится в одном классе несколько строк комментариев будет более чем достаточно, чтобы объяснить, что происходит.
установите null в changeListener перед переключателем check. Вы можете установить прослушиватель снова после проверки переключателя.
radioGroup.setOnCheckedChangeListener(null); radioGroup.check(R.id.radioButton); radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) { } });
моя интерпретация, которая я думаю, что это самый простой
Может быть полезно)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)функции
вот и все
Я думаю, что использование отражения является единственным способом. Что-то вроде этого:
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(); }
мое решение написано на java на основе ответа @Chris:
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); } } });2 флажки и всегда один будет проверен (один должен быть проверен изначально, хотя). Установка тега в true blocks oncheckedchanged listener.
Это простое решение, которое я использовал:
определите пользовательский прослушиватель: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();
public void setCheckedChangeListenerSwitch() { switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean selected) { if (selected) { // do something } else { // do something else } } }); } // Update state & reset listener (so onCheckedNot called) public void updateSwitchState(boolean state){ switch.setOnCheckedChangeListener(null); switch.setChecked(state); setCheckedChangeListenerSwitch(); }
Как насчет этого. Попробуйте использовать тег в представлении
mCheck.setTag("ignore"); mCheck.setChecked(true); mCheck.setTag(null);и
switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean selected) { //If switch has a tag, ignore below if(compoundButton.getTag() != null) return; if (selected) { // do something } else { // do something else } } });
Я нашел все вышеперечисленные ответы слишком сложными. Почему бы просто не создать свой собственный флаг с простым логическим значением?
просто используйте простую систему флагов с логическим значением. Создать
boolean noListener. Всякий раз, когда вы хотите включить/выключить переключатель без запуска какого-либо кода (в этом примере представлен какrunListenerCode(), просто наборnoListener=trueперед вызовомswitch.setChecked(false/true)switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean selected) { if (!noListener) { //If we want to run our code like usual runListenerCode(); } else { //If we simply want the switch to turn off noListener = false; } });очень простое решение с использованием простых флагов. В конце концов, мы установили
noListener=falseв очередной раз так, что наш код продолжает трудиться. Надеюсь, это поможет!
поместите эту проверку внутри OnCheckedChangeListener: compoundButton.isPressed()
фактический код должен быть как ниже:
если(!compoundButton.isPressed()) { возвращаться; }
Это обеспечит статус, был ли переключатель установлен про-грамматически или жестом руки
Comments