web-dev-qa-db-fra.com

Android setOnCheckedChangeListener appelle à nouveau lorsque l'ancienne vue revient

Je ne peux pas résoudre un problème avec la méthode getGroupView. 

le problème est que l'écouteur setOnCheckedChangeListener est appelé plusieurs fois. 

Laissons dire que je vérifie un certain article de case à cocher. Ensuite, je le fais défiler, puis de nouveau en arrière. Ce qui se passe, c'est que l'auditeur est appelé à nouveau. Et le problème est que je stocke les checkbox-id dans un répertoire à l'intérieur de cet écouteur pour l'utiliser plus tard dans le code. La conséquence est que davantage d'éléments sont ajoutés à la liste à chaque fois que l'auditeur est appelé et déforme les données. 

Y a-t-il une solution à cela? que devrais-je faire? Dois-je par exemple annuler l'enregistrement de l'auditeur?

@Override
 public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
     View view = null;

     final int group_position = groupPosition;
     if (convertView == null) {
         LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         view = inflater.inflate(R.layout.activity_phrase, parent, false);
         final ViewHolder viewHolder = new ViewHolder();
         viewHolder.text = (TextView) view.findViewById(R.id.groupTitle);
         viewHolder.checkBox = (CheckBox) view.findViewById(R.id.check);
         viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // TODO Auto-generated method stub

                if (buttonView.isChecked()) {
                    checked.add((Integer) viewHolder.checkBox.getTag());
                }
                else {
                    checked.remove((Integer) viewHolder.checkBox.getTag());
                }

            }
        });

        view.setTag(viewHolder);
        viewHolder.checkBox.setTag(groupPosition);

     } else {
         view = convertView;
         ((ViewHolder)view.getTag()).checkBox.setTag(groupPosition);
     }

     ViewHolder holder = (ViewHolder) view.getTag();
     holder.text.setText(titles[groupPosition]);

     for (int i = 0; i < checked.size(); i++) {
         if (checked.get(i) == group_position) {
             holder.checkBox.setChecked(true);
         }
         else if (checked.get(i) != group_position) {
             holder.checkBox.setChecked(false);
         }
     }

     return view;
 }
22
Björn Hallström

Quelle version d'Android utilisez-vous? 

Cela semble être un problème pour plusieurs composants, en particulier avec une méthode checkedChange () (CheckBox, RadioButton) et je ne peux pas expliquer pourquoi.

Je suppose que parce qu'il enregistre le changement d'état de la position et saisit le changement des autres propriétés? Un problème similaire a été abordé ici

Dans tous les cas, une solution de contournement pourrait consister à ajouter un OnClickListener()

CheckBox yourCheckBox = (CheckBox) findViewById (R.id.yourId);

yourCheckBox.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
                //is chkIos checked?
        if (((CheckBox) v).isChecked()) {
                         //Case 1
        }
        else 
          //case 2

      }
    });
47
Alexey

OnCheckedChangeListener a travaillé pour moi avec une condition si

if(buttonView.isShown())
{
    //ToDo code
}
14
Sonal Bausakar

Ajoutez ce qui suit à ToggleButton layout:

Android:saveEnabled="false"

Cela ferait en sorte qu'Android n'enregistre pas l'état de contrôle dans RestoreInstance et ne provoque pas le changement d'état que vous avez subi.

6
Vignesh Saravana

Définissez le programme d'écoute sur null avant d'appeler la fonction setCheck (), puis sur enable comme suit:

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

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

5
Mahmoud Ibrahim

Ajoutez une instruction if supplémentaire isShown() dans la méthode OnCheckedChange afin de résoudre le problème suivant: OnCheckedChangeListener est appelé plusieurs fois . Il n'est pas nécessaire de passer à onClickListener:

@Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
   if (buttonView.isShown()) { 
        if (buttonView.isChecked()) { 
             //Do something 
        } else { 
             //Do something 
        } 
    } 
}
2
Benjamin Heinke

J'ai fait face au même problème et j'ai lutté pendant plusieurs heures en voyant toutes les discussions à ce sujet. J'ai essayé de résoudre ce problème en conservant viewHolder.checkBox.setTag(groupPosition);
cette déclaration avant viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() cet écouteur. Et le code fonctionne exactement comme prévu.

1
anoop

texte fort Il y a plusieurs façons de résoudre le problème 

checkBoxSelect.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
           // write here your code for example ...
              if(isChecked){
               // do somtheing when is checked
                   }else{
                       // do somthing when is removed the check**strong text**
                        }


        }
    });

** et il y a un autre moyen **

    checkBoxSelect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(((CheckBox)v).isChecked()){
//do something
            }else{
//do something
}
        });
0
Ahmad Saleh

J'étais coincé avec le même problème et j'ai trouvé un moyen de contourner en utilisant l'auditeur de clic

Commencez par vérifier si onclicklistener lui est attribué ou non. Sinon, cela signifie que l'adaptateur définit la valeur pour le premier.

if(!holder.checkbox.hasOnClickListeners())
        {
            holder.checkbox.setChecked(data.get( position ).getSelected());

        }

Maintenant, après avoir vérifié cette 

holder.checkbox.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    data.get( position ).setSelected(holder.checkbox.isChecked());
                    holder.checkbox.setChecked(data.get( position ).getSelected());

                    Toast.makeText(getApplicationContext(),
                            data.get( position ).get_number()+" : "+position, Toast.LENGTH_LONG).show();
                }
            });

Espérons que le problème du défilement disparaisse. Fonctionne bien ici.

0
farhan678