web-dev-qa-db-fra.com

onCheckedChanged appelé automatiquement

J'ai un commutateur dans une vue recyclée et les données sont affichées dans la vue recyclée après la récupération des données à partir de DB. Lorsque la vue recyclée est ouverte, je lis la base de données et, si un champ de la base de données est "Y", j'active le commutateur ou bien je le désactive . Maintenant, le problème est lié au programme d'écoute onCheckedchanged qui est également appelé. être appelé uniquement lorsque l'utilisateur active manuellement le commutateur.

En ouvrant la vue de recyclage ci-dessous est exécutée:

holder.enabledisable.setChecked(messengerRecord.get_is_valid().equalsIgnoreCase("Y"));

Classe ViewHolder:

public class viewHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener{
public SwitchCompat enabledisable;
 public viewHolder(View v) {
            enabledisable = (SwitchCompat) v.findViewById(R.id.enabledisable);
            enabledisable.setOnCheckedChangeListener(this);
...................................
...................................

Méthode OncheckedChanged qui est appelée à l'ouverture de la recyclerView:

@Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            Log.v("ranjith","called oncheckedchanged");
            MessengerRecord rec;
            rec = dbHelper.getRecord(descview.getText().toString());
            switch (buttonView.getId()) {
                case R.id.enabledisable:
                    if (isChecked) {
                        rec.set_is_valid("Y");
                        dbHelper.updateRecord(rec);
                     }
}

Dans le fichier de mise en page:

<Android.support.v7.widget.SwitchCompat
    Android:layout_marginRight="16dp"
    Android:layout_marginEnd="16dp"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:focusable="false"
    Android:id="@+id/enabledisable"
    Android:layout_alignRight="@+id/textview_to"
    Android:layout_alignEnd="@+id/textview_to"
    Android:layout_alignParentRight="true"
    Android:layout_alignParentEnd="true"/>
55
Psypher

C'est bizarre, nous avons tous ce problème, mais pas la réponse officielle de Google à ce problème simple.

Le plus simple est de vérifier:

buttonView.isPressed()

Si la valeur est true, l'utilisateur a cliqué sur la vue.

Aucune variable globale nécessaire.

J'espère que cela t'aides.

195
Sulfkain

J'ai fini par utiliser cette sous-classe de SwitchCompat pour éviter ce problème. De cette façon, je n'ai pas besoin de code passe-partout où j'utilise cette classe . Chaque fois que vous devez modifier la case cochée sans déclencher l'auditeur, utilisez setCheckedSilent au lieu de setChecked:

import Android.content.Context;
import Android.os.Parcelable;
import Android.support.v7.widget.SwitchCompat;
import Android.util.AttributeSet;

/**
 * Created by emanuel on 30/5/16.
 */
public class Switch extends SwitchCompat {

    private OnCheckedChangeListener listener;

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

    @Override
    public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
        this.listener = listener;
        super.setOnCheckedChangeListener(listener);
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        super.setOnCheckedChangeListener(null);
        super.onRestoreInstanceState(state);
        super.setOnCheckedChangeListener(listener);
    }

    public void setCheckedSilent(boolean checked) {
        super.setOnCheckedChangeListener(null);
        super.setChecked(checked);
        super.setOnCheckedChangeListener(listener);
    }
}

onRestoreInstanceState a également déclenché l'écoute, lorsqu'il est défini dans la méthode onViewCreated et que vous revenez à un fragment précédent . J'espère que cela fonctionne pour vous!

11
Emanuel Andrada

Essaye ça

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

        if (buttonView.isPressed()) {
          ... //returns true, if user clicks the switch button        
        }}
3
Shyam Kumar

Cela fonctionne pour moi:

    <pre> 


 boolean selected = preferences.isChecked();
        yourCheckBox.setOnCheckedChangeListener(new 
            CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, 
            boolean isChecked) {
                    if (buttonView.isPressed()) {
               preferences.setChecked(isChecked);
                    } else {
                        yourCheckBox.setChecked(selected);
                    }
                }
            });
    <code>
0
Dima Zatolokin

J'ai rencontré le même problème à l'intérieur de l'écran ViewPager pour les fragments. Lorsque nous basculons entre les fragments, onCheckedChanged Listener est appelé à plusieurs reprises.

Si quelqu'un cherche encore ce problème, essayez-le.

@Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            if (buttonView.isInTouchMode()) {
              ... //Your code will come here.         
            }
}
0
Arthur

utilisez une variable booléenne globale et lorsque vous lisez une donnée de la base de données, définissez-la sur "true". Après vérification (if) dans onCheckChange, définissez-la à nouveau sur "false". dans la première de la méthode onCheckChange, vérifiez si cette variable est fausse, exécutez des codes sinon, retournez (la valeur par défaut de cette variable doit être fausse);

@Override
   public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
     if(!isSourceDB){ 

       Log.v("ranjith","called oncheckedchanged");
        MessengerRecord rec;
        rec = dbHelper.getRecord(descview.getText().toString());
        switch (buttonView.getId()) {
            case R.id.enabledisable:
                if (isChecked) {
                    rec.set_is_valid("Y");
                    dbHelper.updateRecord(rec);

          }
    }//end if
  isSourceDB = false; }// end oncheckedchange
0
mk72