sobre - Android: ¿cómo utilizar CursorAdapter?
simplecursoradapter ejemplo (2)
Tengo una base de datos, un ListView
y un CustomCursorAdapter
que extiende CursorAdapter
. Un botón de menú agrega un elemento a la base de datos. Quiero que el ListView
actualice y muestre este cambio. Normalmente no muestra este nuevo elemento hasta que voy a la pantalla de inicio y vuelvo a abrir la aplicación.
Eventualmente conseguí que funcionara llamando a cursor.requery()
o mCustomCursorAdapter.changeCursor(newCursor)
cada vez que agregué un nuevo elemento, pero cuando configuré autoRequery en falso en el constructor CursorAdapter
, funcionó igual. ¿Por qué se actualiza correctamente cuando autoRequery se establece en falso?
¿Estoy usando CursorAdapter
correctamente? ¿Cuál es la forma estándar de mantener la lista actualizada con la base de datos? ¿Y qué hace autoRequery?
Creé el siguiente método para actualizar ListView:
/**
* Method of refreshing Cursor, Adapter and ListView after database
* changing
*/
public void refreshListView() {
databaseCursor = db.getReadableDatabase().query(
CurrentTableName,
null,
null,
null,
null,
null,
"title"+SortingOrder);
databaseListAdapter = new DomainAdapter(this,
android.R.layout.simple_list_item_2,
databaseCursor,
new String[] {"title", "description"},
new int[] { android.R.id.text1, android.R.id.text2 });
databaseListAdapter.notifyDataSetChanged();
DomainView.setAdapter(databaseListAdapter);
}
End lo llama cada vez después de algún cambio en la base de datos.
La forma idiomática e imho correcta de actualizar automáticamente los Cursor
es llamar a Cursor#setNotificationUri
cuando se crean y antes de entregarlos a lo que sea necesario. Luego, llame a ContentResolver#notifyChange
cuando ContentResolver#notifyChange
algo en el espacio de nombres de Uri de ese Cursor
.
Por ejemplo, suponga que estaba creando una aplicación de correo simple y que desea actualizar cuando llega un nuevo correo, pero también proporciona varias vistas en el correo. Tendría algunos básicos de Uri definidos.
content://org.example/all_mail
content://org.example/labels
content://org.example/messages
Ahora, digamos que quería obtener un cursor que me diera todo el correo y ser actualizado cuando llegue un nuevo correo:
Cursor c;
//code to get data
c.setNotificationUri(getContentResolver(), Uri.parse("content://org.example/all_mail");
Ahora llega el nuevo correo, así que les notifico:
//Do stuff to store in database
getContentResolver().notifyChange(Uri.parse("content://org.example/all_mail", null);
También debo notificar a todos los Cursor
que seleccionaron para etiquetas este nuevo mensaje cumplido
for(String label : message.getLabels() {
getContentResolver().notifyChange(Uri.parse("content://org.example/lables/" + label, null);
}
Y también, tal vez un cursor esté viendo ese mensaje específico, así que notifíquelos también:
getContentResolver().notifyChange(Uri.parse("content://org.example/messages/" + message.getMessageId(), null);
Las llamadas a getContentResolver()
ocurren cuando se accede a los datos. Por lo tanto, si se encuentra en un Service
o ContentProvider
es donde se setNotificationUri
notifyChange
setNotificationUri
y la notifyChange
. No debe hacer eso desde donde se accede a los datos, por ejemplo, una Activity
.
AlarmProvider
es un simple ContentProvider
que utiliza este método para actualizar los Cursor
.