1. ホーム
  2. android

[解決済み] SwitchやCheckboxの値が、ユーザーによって変更されたのか、プログラムによって変更されたのか(リテンションを含む)を区別するにはどうすればよいですか?

2022-08-23 09:41:50

質問

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();
            }
        });

メソッドの実装方法 isNotSetByUser() ?

どのように解決するのですか?

回答2:

とてもシンプルな答えです。

OnCheckedChangeListenerの代わりにOnClickListenerで使用します。

    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);
        }

    });

これでクリックイベントだけを拾って、プログラム的な変更を気にする必要がなくなりました。


回答1:

この問題をカプセル化された方法で処理するラッパークラスを作成しました(Decoratorパターンを参照してください)。

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はXMLでも同じように宣言できますが、コードでGUIを初期化するときにこれを使います。

BetterCheckBox myCheckBox;

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

リスナーをトリガーせずにコードから checked を設定したい場合は myCheckBox.silentlySetChecked(someBoolean) の代わりに setChecked .