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

android, checkbox, listener, onchange

Solution

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`.

Problem

``` setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // How to check whether the checkbox/switch has been checked // by user or it has been checked programatically ? if (isNotSetByUser()) return; handleSetbyUser(); } }); ``` How to implement method `isNotSetByUser()`?

Original source

Related problems