Android: ListView de CheckEdTextView + SQLite, affichez les lignes vérifiées avec l'adaptateur?
-
12-11-2019 - |
Question
J'essaie d'implémenter une liste "Todo" très simple. J'ai choisi d'utiliser un ListView de CheckEdTextView (avec ID Checked_text), la liste utilise Choice_Mode_Multiple bien sûr.
Maintenant, j'utilise la base de données SQLite pour stocker les éléments de la liste.
Pour remplir la liste, j'ai quelque chose comme:
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);
Cela fonctionne correctement, il obtient tous les éléments de la base de données et pour chaque élément, il crée un texte à cocher avec le texte dbadapter.name.
Mais ce dont j'ai vraiment besoin, c'est d'obtenir à la fois le texte et l'état vérifié, et vérifier les lignes en conséquence.
Disons que je peux obtenir l'état (comme entier 0/1) à partir de la base de données en utilisant dbadapter.checked .. Comment puis-je implémenter un adaptateur de curseur qui fait le travail?
J'ai cherché partout (par exemple cette question Ce qui est un gâchis) mais n'a rien trouvé pour résoudre ce problème. Wah. Cela semblait si facile au début.
Merci,
Stefano
@Bert F:
Merci, c'est la méthode que j'utilise pour remplir ma liste:
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);
}
Maintenant, comme test, j'imprime simplement ce qui se passe.
Si j'ajoute 1 élément à la liste, ce que je vois est:
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
Et si je le vérifie ..
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
Atteignez le fait qu'il dit qu'il n'est pas vérifié, pourquoi tire-t-il tant de fois? J'ai juste 1 article: je
Edit: solution laide
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);
}
Avec 2 entrée (d'abord sélectionné deuxième not) lorsque je charge la liste que j'ai:
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
Acclamations.
La solution
Mettre en œuvre un SimplecursorAdapter.ViewBinder.
Avoir le ViewBinder.SetViewValue () Vérifier la méthode pour quand on appelle le
DbAdapter.NAME
colonne ou bien faire vérifier leR.id.checked_text
- Vue de type.Quand il a appelé, mais pas pour ne pas La colonne / vue cible, faites-le revenir
false
afin que l'adaptateur lie la colonne / affichez comme il le ferait normalement.Lorsqu'il prévoyait la colonne / vue cible, faites-le définir le texte et la case à cocher pour le
(CheckedTextView) view
. Ça devrait finir par revenirtrue
Cet adaptateur ne continuera pas à tenter de lier la vue elle-même. Notez que le curseur est disponible pour accéder aux données de requête pour déterminer ou non la case à cocher (DbAdapter.CHECKED
).Définissez votre
ViewBinder
dans tonSimpleCursorAdapter
passant par setViewBinder ()
Voici l'une de mes implémentations ViewBinder. Ce n'est pas pour les boîtes à cocher, mais plutôt pour faire du formatage de fantaisie d'une vue texte, mais cela devrait vous donner une idée de l'approche:
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;
}
};