Frage

Ich habe eine benutzerdefinierte Listview erstellt SimpleCursorAdapter durch die Erweiterung. Das Ergebnis ist, BILD + CheckedTextView (Text + Checkbox).

Wenn ich lange auf ein Element klicken, funktioniert alles einwandfrei -. Ich die richtige ID und Einzelheiten der geklickten Artikel erhalten

Das Problem tritt auf, wenn ich versuche, ein Element zu markieren, wie überprüft, aber es überprüft die falsche Option.

Beispiel: Ich habe 9 Artikel auf meiner Liste, sortiert 1-9. wenn ich auf listItem 1 klicken, wird das Kontrollkästchen auf der Leitung 9 wird geprüft. wenn ich auf Punkt 4 klicken, wird das Kontrollkästchen auf der Leitung 6 wird geprüft, und wenn ich auf der mittleren Zeile klicken, wird es überprüft wird.

Klar bin ich hier fehlt etwas :) Erinnern Sie, wenn ich auf lange die Linie (contextMenu öffnet), alles funktioniert super.

Dies ist der Hörer:

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

            }
        });

Jede mögliche Hilfe schätzen!

Lassen Sie mich wissen, wenn Sie mich brauchen mehr Code zu schreiben.

Danke!

btw, wenn ich auf mehr als ein ... die Party geht weiter ... keine offensichtliche Ordnung ...

EDIT: der Adapter Code

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);
    }
}
War es hilfreich?

Lösung

Mayra ist richtig - das Problem hat mit der Art und Weise zu tun, die Listview Ihre Ansichten sind die Wiederverwendung. Es ist nicht so, wenn es 9 Instanzen des CheckedTextView Objekt sind, je eine pro Ansicht. Stattdessen gibt es eine einzige, die in allen Reihen wiederverwendet wird. So können Sie nicht auf dem CheckedTextView Objekt verlassen, um den Zustand zu halten, ob ein Element aktiviert ist. Sie werden einige zusätzliche Datenstruktur benötigen zu halten, ob eine bestimmte Zeile beispielsweise geprüft wird,

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

Wenn das ith Element ist wahr genau dann, wenn die ith Reihe überprüft werden soll. Dann in Ihrem 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
        }
    });

Dann in der View-Code:

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

Dies sollte Ihr Problem lösen. Ein alternativer Ansatz wäre die Logik zu bewegen, ob die Zeile aktiviert ist oder nicht in das Domain-Objekt, dass die Zeile darstellt. Das wäre meine Präferenz sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top