How can I distinguish whether Switch,Checkbox Value is changed by user or programmatically (including by retention)? How can I distinguish whether Switch,Checkbox Value is changed by user or programmatically (including by retention)? android android

How can I distinguish whether Switch,Checkbox Value is changed by user or programmatically (including by retention)?


Answer 2:

A very simple answer:

Use on OnClickListener instead of OnCheckedChangeListener

    someCheckBox.setOnClickListener(new OnClickListener(){        @Override        public void onClick(View v) {            // you might keep a reference to the CheckBox to avoid this class cast            boolean checked = ((CheckBox)v).isChecked();            setSomeBoolean(checked);        }    });

Now you only pick up click events and don't have to worry about programmatic changes.


Answer 1:

I have created a wrapper class (see Decorator Pattern) which handles this problem in an encapsulated way:

public class BetterCheckBox extends CheckBox {    private CompoundButton.OnCheckedChangeListener myListener = null;    private CheckBox myCheckBox;    public BetterCheckBox(Context context) {        super(context);    }    public BetterCheckBox(Context context, CheckBox checkBox) {        this(context);        this.myCheckBox = checkBox;    }    // assorted constructors here...        @Override    public void setOnCheckedChangeListener(        CompoundButton.OnCheckedChangeListener listener){        if(listener != null) {            this.myListener = listener;        }        myCheckBox.setOnCheckedChangeListener(listener);    }    public void silentlySetChecked(boolean checked){        toggleListener(false);        myCheckBox.setChecked(checked);        toggleListener(true);    }    private void toggleListener(boolean on){        if(on) {            this.setOnCheckedChangeListener(myListener);        }        else {            this.setOnCheckedChangeListener(null);        }    }}

CheckBox can still be declared the same in XML, but use this when initializing your GUI in code:

BetterCheckBox myCheckBox;// later...myCheckBox = new BetterCheckBox(context,    (CheckBox) view.findViewById(R.id.my_check_box));

If you want to set checked from code without triggering the listener, call myCheckBox.silentlySetChecked(someBoolean) instead of setChecked.


Maybe You can check isShown()? If TRUE - than it's user. Works for me.

setOnCheckedChangeListener(new OnCheckedChangeListener() {    @Override    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {        if (myCheckBox.isShown()) {// makes sure that this is shown first and user has clicked/dragged it                  doSometing();        }    }});


Inside the onCheckedChanged() just check whether the user has actually checked/unchecked the radio button and then do the stuff accordingly as follows:

mMySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {   if (buttonView.isPressed()) {       // User has clicked check box    }   else    {       //triggered due to programmatic assignment using 'setChecked()' method.       }  }});