Android SimpleCursorAdapter не обновляется при изменении базы данных
У меня андроид ListActivity
который опирается на базу данных Cursor
через SimpleCursorAdapter
,
Когда по элементам щелкают, поле флага в строке coresponding в базе данных переключается, и представление в списке необходимо обновить.
Проблема в том, что когда обновленное представление выходит за пределы экрана и перерабатывается, старое значение отображается в представлении, когда оно возвращается в представление. То же самое происходит всякий раз, когда список перерисовывается (изменения ориентации и т. Д.).
я использую notifydatasetchanged()
обновить курсор курсора, но это кажется неэффективным.
Как мне обновить базу данных, чтобы курсор тоже обновлялся?
6 ответов
Вызов requery()
на Cursor
когда вы меняете данные в базе данных, которые вы хотите отразить в этом Cursor
(или вещи Cursor
населяет, как ListView
через CursorAdapter
).
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...