Question

J'ai créé un ListView personnalisé en étendant SimpleCursorAdapter. Le résultat est IMAGE + CheckedTextView (texte + cases à cocher).

Quand je clique sur un élément à long, tout fonctionne très bien -. Je reçois le droit ID et détails de l'élément cliqué

Le problème se produit lorsque je tente de marquer un élément comme vérifié, mais il vérifie la mauvaise case.

Par exemple: J'ai 9 articles sur ma liste, triés 1-9. si je clique sur listItem 1, la case à cocher sur la ligne 9 est en cours de vérification. si je clique sur l'article 4, la case de la ligne 6 est en cours de vérification et, si je clique sur la ligne médiane, il est en cours de vérification.

Il est clair que je manque quelque chose ici :) Rappelez-vous quand je clique sur la ligne longue (contextMenu ouvre), tout fonctionne très bien.

Ceci est l'auditeur:

lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                CheckedTextView markedItem = (CheckedTextView) view.findViewById(R.id.btitle);

                if (!markedItem.isChecked()) {
                    markedItem.setChecked(true);
                } else {
                    markedItem.setChecked(false);
                }

            }
        });

Appréciez toute aide!

Laissez-moi savoir si vous avez besoin de moi pour écrire plus de code.

Merci!

BTW, Si je clique sur plus d'un ... La fête continue ... pas d'ordre évident ...

EDIT: le code de l'adaptateur

public class ImageCursorAdapter extends SimpleCursorAdapter {

    private Cursor c;
    private Context context;

    private String url;
    private TextView bUrl;

    public ImageCursorAdapter(Context context, int layout, Cursor c,
            String[] from, int[] to) {
        super(context, layout, c, from, to);
        this.c = c;
        this.context = context;
    }

    public View getView(int pos, View inView, ViewGroup parent) {
        View v = inView;
        if (v == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.image_list, null);
        }

        this.c.moveToPosition(pos);

        final TextView bTitle = (TextView) v.findViewById(R.id.btitle);
        String bookmark = this.c.getString(this.c.getColumnIndex(Browser.BookmarkColumns.TITLE));


        byte[] favicon = this.c.getBlob(this.c.getColumnIndex(Browser.BookmarkColumns.FAVICON));

        if (favicon != null) {
            ImageView iv = (ImageView) v.findViewById(R.id.bimage);
            iv.setImageBitmap(BitmapFactory.decodeByteArray(favicon, 0, favicon.length));
        }
        bTitle.setText(bookmark);

        return (v);
    }
}
Était-ce utile?

La solution

Mayra est juste - le problème a à voir avec la façon dont le ListView réutilise votre point de vue. Il est pas comme s'il y a 9 cas de l'objet CheckedTextView, une par vue. Au lieu de cela, il y a une seule qui est réutilisée dans toutes les lignes. Ainsi, vous ne pouvez pas compter sur l'objet CheckedTextView pour maintenir l'état de savoir si un élément est vérifié. Vous aurez besoin d'une structure de données supplémentaires pour tenir si une ligne donnée est cochée par exemple,

ArrayList<Boolean> checkedStates = new ArrayList<Boolean>();

Lorsque l'élément ith est vrai ssi la ligne ith doit être vérifiée. Ensuite, au sein de votre itemClickListener:

lv.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            boolean currentlyChecked = checkedStates.get(position);
            checkedStates.set(position, !currentlyChecked);
            // Refresh the list
        }
    });

Ensuite, dans votre code de vue:

public View getView(int pos, View inView, ViewGroup parent) {
    View v = inView;
    if (v == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.image_list, null);
    }

    this.c.moveToPosition(pos);

    final TextView bTitle = (TextView) v.findViewById(R.id.btitle);
    String bookmark = this.c.getString(this.c.getColumnIndex(Browser.BookmarkColumns.TITLE));


    byte[] favicon = this.c.getBlob(this.c.getColumnIndex(Browser.BookmarkColumns.FAVICON));

    if (favicon != null) {
        ImageView iv = (ImageView) v.findViewById(R.id.bimage);
        iv.setImageBitmap(BitmapFactory.decodeByteArray(favicon, 0, favicon.length));
    }
    bTitle.setText(bookmark);


    // Change the state of the checkbox to match that of the row's checked state.
    // This check box item is reused for every row, so we need to reset its state each
    // time the row is rendered.
    CheckedTextView markedItem = (CheckedTextView) view.findViewById(R.id.btitle);
    markedItem.setChecked(checkedStates.get(pos));


    return (v);
}

Cela devrait résoudre votre problème. Une autre approche serait de déplacer la logique de savoir si la ligne est cochée ou non dans l'objet de domaine que la ligne représente. Ce serait ma préférence.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top