2 votes

Android, les cases à cocher sont cochées/décochées de façon aléatoire dans une liste extensible.

Utilisation de cet exemple de code de case à cocher de la liste extensible à titre de référence, j'essaie d'enregistrer et de maintenir l'état de la case à cocher. Cependant, des cases à cocher aléatoires sont cochées et décochées (ce qui déclenche mon processus d'enregistrement). OnCheckedChangeListener avec les nouvelles valeurs ) lorsque je les fais défiler hors de vue, que je minimise leur groupe, ou même que je minimise/maximise un groupe voisin !

public Object getChild(int groupPosition, int childPosition) {
    return colors.get( groupPosition ).get( childPosition );
}

public long getChildId(int groupPosition, int childPosition) {
    return (long)( groupPosition*1024+childPosition );  // Max 1024 children per group
}

public View getChildView(final int groupPosition, final int childPosition, 
        boolean isLastChild, View convertView, ViewGroup parent) {

    View v = null;
    if( convertView != null ) {
        v = convertView;
    } else {
        v = inflater.inflate(R.layout.child_row, parent, false); 
    }

    Color c = (Color)getChild( groupPosition, childPosition );

    TextView color = (TextView)v.findViewById( R.id.childname );
    if( color != null ) {
        color.setText( c.getColor() );
    }

    TextView rgb = (TextView)v.findViewById( R.id.rgb );
    if( rgb != null ) {
        rgb.setText( c.getRgb() );
    }

    CheckBox cb = (CheckBox)v.findViewById( R.id.check1 );
    cb.setChecked( c.getState() );
    cb.setOnCheckedChangeListener(new OnCheckedChangeListener()
    {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
        {
            colors.get(groupPosition).get(childPosition).setState(isChecked);
            context.setColorBool(groupPosition, childPosition, isChecked);
            Log.d("ElistCBox2", "listitem position: " +groupPosition+"/"+childPosition+" "+isChecked);
        }
    });

    return v;
}

Je ne sais pas quel morceau de code pourrait être responsable de cela, donc toute suggestion sur ce qu'il faut inclure ici est la bienvenue. Mon code ne diffère de l'original que dans ma tentative de sauvegarder les valeurs.

0voto

Jeffrey Blattman Points 8891

Je pense que lorsque votre adaptateur crée des vues, l'écouteur de contrôle est appelé lorsque la vue de la case à cocher est initialisée. De nombreux widgets sous Android fonctionnent de cette manière... l'écouteur est appelé lorsque la vue est initialisée.

je ne sais pas pourquoi les choses fonctionnent ainsi, mais c'est peut-être pour permettre au code client de s'initialiser de manière cohérente. par exemple, que la case soit cochée par l'utilisateur ou qu'elle soit initialisée comme cochée, exécutez le même code.

pour contrer cela, vous pouvez essayer de faire quelque chose comme mettre un drapeau dans votre classe d'écouteur impl pour vous permettre d'ignorer le premier clic, quelque chose comme,

cb.setOnCheckedChangeListener(new OnCheckedChangeListener()
    {
        private void first = true;

        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
        {
            if (first) {
              first = false;
              return;
            }

            colors.get(groupPosition).get(childPosition).setState(isChecked);
            context.setColorBool(groupPosition, childPosition, isChecked);
            Log.d("ElistCBox2", "listitem position: " +groupPosition+"/"+childPosition+" "+isChecked);
        }
    });

également, assurez-vous que vous réutilisez correctement convertView dans votre mise en œuvre de getView() dans votre adaptateur. Par exemple,

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if (view == null) {
        view = inflater.inflate(R.layout.applications_item, null);
    }

0voto

Il s'agit d'une très vieille question, mais je me suis débattu avec le même problème, alors voici ma réponse pour tous ceux qui cherchent :

Le plus simple est d'utiliser CheckBox.onClickListener au lieu de onCheckedChangeListener.

Cela n'est que légèrement ennuyeux en termes de réorganisation de votre logique, mais cela garantira que lorsque les cases sont décochées de manière aléatoire (par exemple, en développant un groupe adjacent), l'événement ne se déclenchera pas.

Honnêtement, je pense que cela devrait être considéré comme un bug, même si je suis sûr que le comportement peut être expliqué à partir de la source Android.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X