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