Android SimpleCursorAdapter не обновляется при изменении базы данных

видео ListActivity это поддерживается базой данных Cursor через SimpleCursorAdapter.

когда элементы нажаты, поле флага в строке coresponding в базе данных переключается, и представление в списке должно быть обновлено.

проблема в том, что когда обновленное представление выходит из экрана и перерабатывается, старое значение отображается в представлении, когда оно возвращается в представление. То же самое происходит, когда чет список redrawb (изменения ориентации и т. д.).

Я использую notifydatasetchanged() обновить адаптер курсора, но это кажется неэффективным.

как я должен обновлять базу данных, чтобы курсор также обновлялся?

6 ответов


вызов requery() на Cursor при изменении данных в базе данных, которые вы хотите отразить в этом Cursor (или вещи Cursor заполняет, как ListView через CursorAdapter).

A Cursor сродни курсору на стороне клиента ODBC - он содержит все данные, представленные результатом запроса. Следовательно, только потому, что вы меняете данные в базе данных,Cursor не будет знать об этих изменениях, если вы не обновите его через requery().


обновление: весь этот вопрос и набор ответов должны быть удалены из-за старости, но это, по-видимому, невозможно. Любой, кто ищет ответы на Android, должен иметь в виду, что Android-это быстро движущаяся цель, а ответы с 2009 года, как правило, хуже, чем новые ответы.

нынешнее решение Получить свежий Cursor и использовать changeCursor() или swapCursor() на CursorAdapter чтобы повлиять на изменение данных.


requery теперь устарел. от документация:

этот метод устарел. Не используй это. Просто запросите новый курсор, чтобы вы могли сделать это асинхронно и обновить представление списка после возвращения нового курсора.

после получения нового курсора можно использоватьadapter.changeCursor(cursor). это должно обновить представление.


в случае использования загрузчика и автоматически сгенерированного курсора вы можете вызвать:

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

в вашей деятельности, сразу после изменения чего-то в БД, для регенерации нового курсора. Не забудьте также определить обработчики событий:

@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);
}

Я не ясно, если вы установите autoRequery собственность CursorAdapter к true.

адаптер проверки autoRequery свойство; если это false, то курсор не будет изменен.


requery() уже устарел, просто реализуйте такой простой метод updateUI () в дочернем классе CursorAdapter и вызывайте его после обновления данных:

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

Это легко.

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

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

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

или используйте CursorLoader...