2010-08-23 20 views
16

Tengo una base de datos, ListView, y CustomCursorAdapter que se extiende CursorAdapter. Un botón de menú agrega un elemento a la base de datos. Quiero que el ListView se actualice y muestre este cambio. Normalmente no muestra este nuevo elemento hasta que vaya a la pantalla de inicio y vuelva a abrir la aplicación.Android: cómo usar CursorAdapter?

Yo finalmente conseguir que funcione llamando cursor.requery() o mCustomCursorAdapter.changeCursor(newCursor) cada vez que he añadido un nuevo elemento, pero cuando me puse autoRequery en false en el CursorAdapter constructor, que funcionaba de la misma manera. ¿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?

+0

@randzero significa que desea actualizar los elementos de vista de lista cada vez que se añade nuevo elemento en la base de datos , Es correcto ? –

Respuesta

37

La forma correcta e idiomática de actualizar automáticamente Cursor s es llamar al Cursor#setNotificationUri cuando se crean y antes de que se transfieran a lo que se les solicite. Luego llame al ContentResolver#notifyChange cuando cambie cualquier cosa en el espacio de nombre de Uri Cursor.

Por ejemplo, suponga que está creando una aplicación de correo simple y desea actualizar cuando llega un nuevo correo, pero también proporciona varias vistas en el correo. Tendría algunos Uri básicos definidos.

content://org.example/all_mail 
content://org.example/labels 
content://org.example/messages 

Ahora, dicen que quería obtener un cursor que me dio todo el correo y actualizarse cuando llegue correo nuevo:

Cursor c; 
//code to get data 
c.setNotificationUri(getContentResolver(), Uri.parse("content://org.example/all_mail"); 

Ahora llega un nuevo correo, así que notificar:

//Do stuff to store in database 
getContentResolver().notifyChange(Uri.parse("content://org.example/all_mail", null); 

También debería notificar a todos los Cursor s que seleccionaron para las etiquetas este nuevo mensaje se reunió

for(String label : message.getLabels() { 
    getContentResolver().notifyChange(Uri.parse("content://org.example/lables/" + label, null); 
} 

Y también, tal vez un cursor está viendo que un mensaje específico para notificar a ellos, así:

getContentResolver().notifyChange(Uri.parse("content://org.example/messages/" + message.getMessageId(), null); 

Las llamadas getContentResolver() suceda en el que se accede a los datos. Entonces, si está en un Service o ContentProvider es donde setNotificationUri y notifyChange. No debe hacer eso desde donde se accede a los datos, por ejemplo, un Activity.

AlarmProvider es un simple ContentProvider que utiliza este método para actualizar Cursor s.

+1

Esto fue realmente útil. Gracias por compartir. –

+0

¡Esta publicación es realmente genial! ¡Me ayudó mucho también en mi búsqueda! :) –

+0

Corrígeme si estoy equivocado 'Cursor # setNotificationUri' actualiza el cursor con los datos más recientes cuando se trata de un' getContentResolver(). NotifyChanged' es un llamado en 'ContentProvider'. –

1

creé siguiente método para ListView actualización:

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

final lo llama cada vez que después de algún cambio en la base de datos

Cuestiones relacionadas