Подтвердить что ты не робот

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

У меня есть Android ListActivity, который поддерживается базой данных Cursor через SimpleCursorAdapter.

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

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

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

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

4b9b3361

Ответ 1

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

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


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

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

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 4

Непонятно, если вы установили свойство autoRequery для CursorAdapter в true.

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

Ответ 5

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

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

Ответ 6

Это легко.

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...