it-swarm.com.de

Android SimpleCursorAdapter wird nicht aktualisiert, wenn sich die Datenbank ändert

Ich habe eine Android ListActivity, die durch eine Datenbank Cursor durch eine SimpleCursorAdapter gesichert wird.

Wenn Sie auf die Elemente klicken, wird ein Flag-Feld in der entsprechenden Zeile in der Datenbank umgeschaltet, und die Ansicht in der Liste muss aktualisiert werden. 

Das Problem besteht darin, dass der alte Wert in der Ansicht angezeigt wird, wenn die Ansicht, die aktualisiert wurde, nicht mehr angezeigt wird und wiederverwendet wird. Das gleiche passiert, wenn die Liste neu gezeichnet wird (Orientierungsänderungen usw.). 

Ich verwende notifydatasetchanged(), um den Cursoradapter zu aktualisieren, aber er scheint unwirksam zu sein.

Wie soll ich die Datenbank aktualisieren, damit auch der Cursor aktualisiert wird?

43

Rufen Sie requery() für die Cursor auf, wenn Sie Daten in der Datenbank ändern, die in dieser Cursor wiedergegeben werden sollen (oder wenn sich die Cursor wie eine ListView über eine CursorAdapter auffüllt).

Eine Cursor ähnelt einem clientseitigen Cursor ODBC - er enthält alle Daten, die durch das Abfrageergebnis dargestellt werden. Nur weil Sie die Daten in der Datenbank ändern, kennt die Cursor diese Änderungen nicht, es sei denn, Sie aktualisieren sie über requery().


UPDATE: Diese ganze Frage und die Antworten sollten aus Altersgründen gelöscht werden, aber das ist anscheinend unmöglich. Wer Android-Antworten sucht, sollte bedenken, dass Android ein sich schnell bewegendes Ziel ist. Antworten aus dem Jahr 2009 sind in der Regel schlechter als neuere Antworten.

Die aktuelle Lösung besteht darin, eine neue Cursor zu erhalten und entweder changeCursor() oder swapCursor() für die CursorAdapter zu verwenden, um eine Datenänderung zu beeinflussen.

90
CommonsWare

requery ist jetzt veraltet. aus der Dokumentation :

Diese Methode ist veraltet . Verwenden Sie das nicht. Fordern Sie einfach einen neuen Cursor an, damit Sie dies asynchron durchführen können und Ihre Listenansicht aktualisieren, sobald der neue Cursor zurückkommt.

nachdem Sie einen neuen Cursor erhalten haben, können Sie dieadapter.changeCursor(cursor) verwenden. Dies sollte die Ansicht aktualisieren.

37
rony l

Bei Verwendung des Loader und des automatisch generierten Cursors können Sie Folgendes aufrufen:

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

in Ihrer Aktivität, kurz nachdem Sie etwas in einer Datenbank geändert haben, können Sie den neuen Cursor neu generieren.

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    CursorLoader cursorLoader =
            new CursorLoader(this,
                    YOUR_URI,
                    YOUR_PROJECTION, null, null, null);
    return cursorLoader;
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    adapter.swapCursor(data);
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    adapter.swapCursor(null);
}
21
siefca

Ich bin nicht klar, wenn Sie die autoRequery-Eigenschaft von CursorAdapter auf true setzen.

Der Adapter überprüft die Eigenschaft autoRequery. Wenn es sich um false handelt, wird der Cursor nicht geändert.

1
gjican

Es ist einfach. 

private Db mDbAdapter;
private Cursor mCursor;
private SimpleCursorAdapter mCursorAd;

.....................................
//After removing the item from the DB, use this
.....................................

 mCursor = mDbAdapter.getAllItems();
 mCursorAd.swapCursor(mCursor);

Oder verwenden Sie den CursorLoader ...

0
Shwarz Andrei

requery () ist bereits veraltet. Implementieren Sie einfach die einfache updateUI () -Methode wie folgt in der untergeordneten Klasse Ihres CursorAdapter und rufen Sie sie nach Datenaktualisierungen auf:

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