Android:Listenansicht von CheckedTextView + SQLite, überprüfte Zeilen mit Adapter anzeigen?
-
12-11-2019 - |
Frage
Ich versuche eine sehr einfache "Todo" -Liste zu implementieren.Ich habe mich für eine Listenansicht von CheckedTextView (mit der ID checked_text) entschieden, die Listenansicht verwendet natürlich CHOICE_MODE_MULTIPLE.
Jetzt verwende ich die SQLite-Datenbank, um die Listenelemente zu speichern.
Um die Liste zu füllen, habe ich so etwas wie:
cursor = dbHelper.fetchAll();
startManagingCursor(cursor);
String[] from = new String[] { DbAdapter.NAME };
int[] to = new int[] { R.id.checked_text };
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.todo_multi_row, cursor, from, to);
listView.setAdapter(notes);
Dies funktioniert einwandfrei, es werden alle Elemente in der Datenbank und für jeden abgerufen element es erstellt eine CheckedTextView mit als Text DbAdapter.NAME .
Aber was ich wirklich brauche, ist sowohl den Text als auch den überprüften Status zu erhalten, und überprüfen Sie die Zeilen entsprechend.
Nehmen wir an, ich kann den Status (als Ganzzahl 0/1) aus der Datenbank abrufen mit DBAdapter.FT..wie kann ich einen Cursoradapter implementieren, der das erhält arbeit erledigt?
Ich habe überall gesucht (zum Beispiel diese Frage was ein Durcheinander ist), aber nichts gefunden, um dieses Problem zu lösen.Wah.Anfangs schien es so einfach zu sein.
Danke,
Stefanos
@Bert F:
Danke, das ist die Methode, mit der ich meine Liste fülle:
private void fillData() {
Log.d("LIST","fill");
cursor = dbHelper.fetchAllTodos();
startManagingCursor(cursor);
String[] from = new String[] { TodoDbAdapter.NAME };
int[] to = new int[] { R.id.checked_text };
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.todo_multi_row, cursor, from, to);
final SimpleCursorAdapter.ViewBinder mViewBinder =
new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(
final View view,
final Cursor cursor,
final int columnIndex) {
Log.d("LIST",view +" "+cursor+" "+columnIndex);
CheckedTextView item = (CheckedTextView) view;
Log.d("LIST","NAME: "+item.getText()+" State: "+item.isChecked());
return false;
}
};
notes.setViewBinder(mViewBinder);
listView.setAdapter(notes);
}
Jetzt drucke ich als Test nur aus, was passiert.
Wenn ich der Liste 1 Element hinzufüge, sehe ich Folgendes:
02-12 14:45:35.913: DEBUG/LIST(22621): fill
02-12 14:45:35.933: DEBUG/LIST(22621): android.widget.CheckedTextView@479da398 android.database.sqlite.SQLiteCursor@479d98f0 2
02-12 14:45:35.933: DEBUG/LIST(22621): NAME: State: false
02-12 14:45:35.933: DEBUG/LIST(22621): android.widget.CheckedTextView@479da398 android.database.sqlite.SQLiteCursor@479d98f0 2
02-12 14:45:35.943: DEBUG/LIST(22621): NAME: first item State: false
02-12 14:45:36.013: DEBUG/LIST(22621): android.widget.CheckedTextView@479dc6c0 android.database.sqlite.SQLiteCursor@479d98f0 2
02-12 14:45:36.013: DEBUG/LIST(22621): NAME: State: false
02-12 14:45:36.223: DEBUG/LIST(22621): android.widget.CheckedTextView@479dc6c0 android.database.sqlite.SQLiteCursor@479d98f0 2
02-12 14:45:36.223: DEBUG/LIST(22621): NAME: first item State: false
Und wenn ich es überprüfe..
02-12 14:53:33.123: DEBUG/LIST(22621): android.widget.CheckedTextView@479dc6c0 android.database.sqlite.SQLiteCursor@479d98f0 2
02-12 14:53:33.123: DEBUG/LIST(22621): NAME: first item State: false
02-12 14:53:33.123: DEBUG/LIST(22621): android.widget.CheckedTextView@479da398 android.database.sqlite.SQLiteCursor@479d98f0 2
02-12 14:53:33.123: DEBUG/LIST(22621): NAME: first item State: false
Lassen Sie die Tatsache beiseite, dass es sagt, dass es nicht überprüft wird, warum feuert es so oft?Ich habe nur 1 Artikel: Ich
BEARBEITEN:hässliche Lösung
private void fillData() {
Log.d("LIST","fill");
cursor = dbHelper.fetchAllTodos();
startManagingCursor(cursor);
String[] from = new String[] { TodoDbAdapter.NAME };
int[] to = new int[] { R.id.checked_text };
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.todo_multi_row, cursor, from, to);
final SimpleCursorAdapter.ViewBinder mViewBinder =
new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(
final View view,
final Cursor cursor,
final int columnIndex) {
final int checkedIndex =
cursor.getColumnIndexOrThrow(
TodoDbAdapter.CHECKED);
Log.d("LIST","VIEW: "+view+" NAME: "+cursor.getString(columnIndex)+" "+cursor.getInt(checkedIndex));
return false;
}
};
notes.setViewBinder(mViewBinder);
listView.setAdapter(notes);
}
Mit 2 Einträgen (erster ausgewählter zweiter nicht) beim Laden der Liste habe ich:
02-12 15:59:48.613: DEBUG/LIST(23533): fill
02-12 15:59:48.643: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a30ec0 NAME: test 1
02-12 15:59:48.653: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a30ec0 NAME: LOL 0
02-12 15:59:48.683: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a30ec0 NAME: test 1
02-12 15:59:48.683: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a331f8 NAME: LOL 0
02-12 15:59:48.713: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a35770 NAME: test 1
02-12 15:59:48.713: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a35770 NAME: LOL 0
02-12 15:59:48.783: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a35770 NAME: test 1
02-12 15:59:48.783: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a35770 NAME: LOL 0
Jubel.
Lösung
Implementieren Sie eine Einfacher CursorAdapter.Ansichtsbinder.
Haben die ViewBinder.setViewValue() methodenprüfung, wann es für die aufgerufen wird
DbAdapter.NAME
spalte oder lassen Sie es auf die überprüfenR.id.checked_text
-typ-Ansicht.Wenn es anrief, aber nicht für nicht die Zielspalte / -ansicht, lassen Sie sie zurückgeben
false
damit der Adapter die Spalte / Ansicht so bindet, wie es normalerweise der Fall wäre.Wenn es die Zielspalte / -ansicht aufruft, lassen Sie es den Text und das Kontrollkästchen für die
(CheckedTextView) view
.Es sollte am Ende zurückkehrentrue
dieser Adapter versucht also nicht mehr, die Ansicht selbst zu binden.Beachten Sie, dass der Cursor für den Zugriff auf Abfragedaten verfügbar ist, um zu bestimmen, ob das Kontrollkästchen aktiviert werden soll oder nicht (DbAdapter.CHECKED
).Stellen Sie Ihre
ViewBinder
in IhremSimpleCursorAdapter
über setViewBinder()
Hier ist eine meiner ViewBinder Implementierungen.Es ist nicht für Kontrollkästchen gedacht, sondern für die ausgefallene Formatierung einer Textansicht, aber es sollte Ihnen eine Idee für den Ansatz geben:
private final SimpleCursorAdapter.ViewBinder mViewBinder =
new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(
final View view,
final Cursor cursor,
final int columnIndex) {
final int latitudeColumnIndex =
cursor.getColumnIndexOrThrow(
LocationDbAdapter.KEY_LATITUDE);
final int addressStreet1ColumnIndex =
cursor.getColumnIndexOrThrow(
LocationDbAdapter.KEY_ADDRESS_STREET1);
if (columnIndex == latitudeColumnIndex) {
final String text = formatCoordinates(cursor);
((TextView) view).setText(text);
return true;
} else if (columnIndex == addressStreet1ColumnIndex) {
final String text = formatAddress(cursor);
((TextView) view).setText(text);
return true;
}
return false;
}
};