Android - programmatically change the state of a switch without triggering OnCheckChanged listener

Set the listener to null before calling setCheck() function, and enable it after that, such as the following:

switch.setOnCheckedChangeListener (null);
switch.setChecked(true);
switch.setOnCheckedChangeListener (this);

Reference: Change Checkbox value without triggering onCheckChanged


Well, just before doing things in code with the switch you could just unregister the Listener, then do whatever you need to, and again register the listener.


Every CompoundButton (two states button - on/off) has a pressed state which is true only when a user is pressing the view.

Just add a check in your listener before starting the actual logic:

if(compoundButton.isPressed()) {
    // continue with your listener
}

That way, changing the checked value programmatically won't trigger the unwanted code.

From @krisDrOid answer.


I have one solution and its working fine at my end. I have added setOnTouchListener and setOnCheckedChangeListener on my switch control, and added following code to solve my problem.

    // set tag by default.
    mMySwitch.setTag("TAG");

    // Add OnCheckedChangeListener.
    mMySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
         @Override
         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (mMySwitch.getTag() != null) {
                 mMySwitch.setTag(null);
                 return;
                }

          // Do your stuff here.
        }
    });

    // Add Touch listener.
    mMySwitch.setOnTouchListener(new View.OnTouchListener() {
         @Override
         public boolean onTouch(View v, MotionEvent event) {
            mMySwitch.setTag(null);
            return false;
         }
    });

In this way setOnCheckedChangeListener is getting called only when check changed happens by human intervention by drag, by click, by touch.

Also don't forgot to add your valid string tag ( not null ) when your trying to change check status of switch control. like :

 mMySwitch.setTag("TAG");
 mMySwitch.setChecked(true);

Write a custom Switch or SwitchCompat and override the setOnCheckedListener.

public class SwitchCompat extends android.support.v7.widget.SwitchCompat {
private boolean mIgnoreCheckedChange = false;

public SwitchCompat(Context context) {
    super(context);
}

public SwitchCompat(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public SwitchCompat(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}


@Override
public void setOnCheckedChangeListener(final OnCheckedChangeListener listener) {
    super.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (mIgnoreCheckedChange) {
                return;
            }
            listener.onCheckedChanged(buttonView, isChecked);
        }
    });
}

public void setChecked(boolean checked, boolean notify) {
    mIgnoreCheckedChange = !notify;
    setChecked(checked);
    mIgnoreCheckedChange = false;
}

}