当数据库更改时,Android SimpleCursorAdapter 不会更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1985955/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:04:28  来源:igfitidea点击:

Android SimpleCursorAdapter doesn't update when database changes

databaseandroidsqlitecursorlistactivity

提问by CodeFusionMobile

I have an Android ListActivitythat is backed by a database Cursorthrough a SimpleCursorAdapter.

我有一个AndroidListActivity是由数据库支持Cursor通过SimpleCursorAdapter

When the items are clicked, a flag field in the coresponding row in the database is toggled and the view in the list needs to be updated.

当项目被点击时,数据库中对应行的标志字段被切换,列表中的视图需要更新。

The problem is, when the view that's updated goes off screen and is recycled, the old value is displayed on the view when it returns into view. The same thing happens whenever thr list is redrawb (orientation changes, etc).

问题是,当更新的视图离开屏幕并被回收时,旧值在返回视图时显示在视图上。每当重绘 thr 列表(方向更改等)时,都会发生同样的事情。

I use notifydatasetchanged()to refresh the cursor adapter but it seems ineffective.

notifydatasetchanged()用来刷新游标适配器,但似乎无效。

How should I be updating the database so the cursor is updated as well?

我应该如何更新数据库以便更新游标?

回答by CommonsWare

Call requery()on the Cursorwhen you change data in the database that you want reflected in that Cursor(or things the Cursorpopulates, like a ListViewvia a CursorAdapter).

呼叫requery()Cursor,当你改变数据库中的数据,你想反映在Cursor(或事物的Cursor填充,如ListView通过CursorAdapter)。

A Cursoris akin to an ODBC client-side cursor -- it holds all of the data represented by the query result. Hence, just because you change the data in the database, the Cursorwill not know about those changes unless you refresh it via requery().

ACursor类似于 ODBC 客户端游标——它保存由查询结果表示的所有数据。因此,仅仅因为您更改了数据库中的数据,Cursor除非您通过requery().



UPDATE: This whole question and set of answers should be deleted due to old age, but that's apparently impossible. Anyone seeking Android answers should bear in mind that the Android is a swiftly-moving target, and answers from 2009 are typically worse than are newer answers.

更新:由于年老,这整个问题和一组答案应该被删除,但这显然是不可能的。任何寻求 Android 答案的人都应该记住,Android 是一个快速移动的目标,2009 年的答案通常比新的答案更糟糕。

The current solution is to obtain a fresh Cursorand use either changeCursor()or swapCursor()on the CursorAdapterto affect a data change.

目前的解决方案是,以获得新鲜的Cursor,并使用任一changeCursor()swapCursor()CursorAdapter以影响数据的变化。

回答by rony l

requeryis now deprecated. from the documentation:

requery现在已弃用。从文档

This method is deprecated. Don't use this. Just request a new cursor, so you can do this asynchronously and update your list view once the new cursor comes back.

此方法已弃用。不要用这个。只需请求一个新游标,这样您就可以异步执行此操作,并在新游标返回后更新您的列表视图。

after obtaining a new cursor one can use theadapter.changeCursor(cursor). this should update the view.

获得新游标后,可以使用adapter.changeCursor(cursor). 这应该更新视图。

回答by siefca

In case of using loader and automagically generated cursor you can call:

如果使用加载器和自动生成的游标,您可以调用:

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

in your activity, just after changing something on a DB, to regenerate new cursor. Don't forget to also have event handlers defined:

在您的活动中,在更改数据库上的某些内容后,重新生成新游标。不要忘记还定义了事件处理程序:

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

回答by gjican

I am not clear if you set the autoRequeryproperty of CursorAdapter to true.

我不清楚你是否将autoRequeryCursorAdapter的属性设置为true.

The adapter will check the autoRequeryproperty; if it is false, then the cursor will not be changed.

适配器会检查autoRequery属性;如果是false,则光标不会改变。

回答by Jaroslav

requery() is already deprecated, just implement the simple updateUI() method like this in your CursorAdapter's child class and call it after data updates:

requery() 已被弃用,只需在 CursorAdapter 的子类中实现简单的 updateUI() 方法,并在数据更新后调用它:

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

回答by Shwarz Andrei

It's easy.

这很简单。

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

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

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

Or use CursorLoader...

或者使用 CursorLoader ...