web-dev-qa-db-fra.com

Android - modifiez par programme l'état d'un commutateur sans déclencher l'écouteur OnCheckChanged


Je recherche une méthode pour changer par programme l'état d'un widget Android Switch en utilisant switch.setChecked(true); sans déclencher OnCheckedChangedlistener.

Ma première pensée a été de l'échanger contre un OnClickListener mais comme cela enregistre uniquement les clics et que vous pouvez non seulement cliquer mais aussi faire glisser un commutateur, il n'est pas vraiment adapté à l'usage prévu comme si le l'utilisateur devait faire glisser le commutateur de off à on, puis le commutateur ne ferait rien car l'utilisateur ne clique pas ...

Si quelqu'un a une solution ou une solution intelligente pour cela, ce serait génial

36
Paul Alexander

Eh bien, juste avant de faire des choses dans le code avec le commutateur, vous pouvez simplement désinscrire l'écouteur, puis faire tout ce que vous devez faire et enregistrer à nouveau l'écouteur.

29
smnpl

Définissez l'écouteur sur null avant d'appeler la fonction setCheck () et l'activer après cela, comme par exemple:

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

Référence : Modifier la valeur de la case à cocher sans déclencher onCheckChanged

34
Mahmoud Ibrahim

J'ai une solution et ça marche bien de mon côté. J'ai ajouté setOnTouchListener et setOnCheckedChangeListener sur mon contrôle de commutateur, et ajouté le code suivant pour résoudre mon problème.

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

De cette façon, setOnCheckedChangeListener est appelé uniquement lorsque la vérification a été effectuée par une intervention humaine par glisser, cliquer, toucher.

N'oubliez pas non plus d'ajouter votre balise de chaîne valide (non nulle) lorsque vous essayez de modifier l'état de vérification du contrôle de commutateur. comme :

 mMySwitch.setTag("TAG");
 mMySwitch.setChecked(true);
16
Chetan Bhoyar

Écrivez un Switch ou SwitchCompat personnalisé et remplacez 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;
}

}
8
hyb1996

Chaque CompoundButton (bouton à deux états - marche/arrêt) a un état enfoncé qui est vrai uniquement lorsqu'un utilisateur appuie sur la touche vue .

Ajoutez simplement une vérification dans votre écouteur avant de démarrer la logique réelle:

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

De cette façon, la modification de la valeur vérifiée par programme ne déclenchera pas le code indésirable.

De @ krisDrOid réponse.

6
ronginat