Android SimpleCursorAdapter no se actualiza cuando cambia la base de datos

Tengo una ListActivity Android respaldada por un Cursor base de datos a través de SimpleCursorAdapter .

Cuando se hace clic en los elementos, un campo de bandera en la fila correspondiente en la base de datos se alterna y la vista en la lista necesita ser actualizada.

El problema es que cuando la vista que se actualiza sale de la pantalla y se recicla, el valor anterior se muestra en la vista cuando vuelve a la vista. Lo mismo ocurre siempre que la lista se redibuja (la orientación cambia, etc.).

Utilizo notifydatasetchanged() para actualizar el adaptador del cursor, pero parece ineficaz.

¿Cómo debería actualizar la base de datos para que el cursor también se actualice?

Llamar a requery() en el Cursor cuando cambia los datos en la base de datos que desea reflejar en ese Cursor (o cosas que el Cursor rellena, como un ListView través de un CursorAdapter ).

Un Cursor es similar a un cursor ODBC del lado del cliente, contiene todos los datos representados por el resultado de la consulta. Por lo tanto, solo porque cambie los datos en la base de datos, el Cursor no conocerá esos cambios a menos que los actualice a través de requery() .


ACTUALIZACIÓN : toda esta pregunta y conjunto de respuestas deben eliminarse debido a la vejez, pero eso es aparentemente imposible. Cualquiera que busque respuestas de Android debe tener en cuenta que Android es un objective que se mueve rápidamente, y las respuestas de 2009 suelen ser peores que las respuestas más recientes.

La solución actual es obtener un Cursor nuevo y usar changeCursor() o swapCursor() en CursorAdapter para afectar un cambio de datos.

requery ahora está en desuso. de la documentación :

Este método está en desuso. No uses esto Solo solicite un cursor nuevo, para que pueda hacerlo de forma asincrónica y actualice su vista de lista una vez que el cursor nuevo regrese.

después de obtener un nuevo cursor uno puede usar el adapter.changeCursor(cursor) . esto debería actualizar la vista.

En caso de utilizar el cargador y el cursor generado automáticamente puede llamar:

 getLoaderManager().restartLoader(0, null, this); 

en su actividad, justo después de cambiar algo en una base de datos, para regenerar el cursor nuevo. No olvides tener también manejadores de eventos definidos:

 @Override public Loader onCreateLoader(int id, Bundle args) { CursorLoader cursorLoader = new CursorLoader(this, YOUR_URI, YOUR_PROJECTION, null, null, null); return cursorLoader; } @Override public void onLoadFinished(Loader loader, Cursor data) { adapter.swapCursor(data); } @Override public void onLoaderReset(Loader loader) { adapter.swapCursor(null); } 

No estoy seguro si configura la propiedad autoRequery de CursorAdapter como true .

El adaptador verificará la propiedad de autoRequery ; si es false , entonces el cursor no cambiará.

requery () ya está en desuso, simplemente implemente el método simple updateUI () como este en la clase secundaria de su CursorAdapter y llámelo después de las actualizaciones de datos:

 private void updateUI(){ swapCursor(dbHelper.getCursor()); notifyDataSetChanged(); } 

Es fácil.

 private Db mDbAdapter; private Cursor mCursor; private SimpleCursorAdapter mCursorAd; ..................................... //After removing the item from the DB, use this ..................................... mCursor = mDbAdapter.getAllItems(); mCursorAd.swapCursor(mCursor); 

O usa CursorLoader …