Android:如何使用 CursorAdapter?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3544913/
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 10:42:20  来源:igfitidea点击:

Android: how to use CursorAdapter?

androidandroid-cursoradapter

提问by user316146

I have a database, a ListView, and a CustomCursorAdapterthat extends CursorAdapter. A menu button adds an item to the database. I want the ListViewto update and show this change. Normally it doesn't show this new item until i go to the homescreen and reopen the application.

我有一个数据库,aListView和一个CustomCursorAdapter扩展CursorAdapter. 菜单按钮向数据库添加项目。我希望ListView更新并显示此更改。通常它不会显示这个新项目,直到我转到主屏幕并重新打开应用程序。

I did eventually get it to work by calling cursor.requery()or mCustomCursorAdapter.changeCursor(newCursor)whenever I added a new item, but when I set autoRequery to false in the CursorAdapterconstructor, it worked just the same. Why does it update correctly when autoRequery is set to false?

我最终确实通过调用cursor.requery()mCustomCursorAdapter.changeCursor(newCursor)每当我添加了一个新项目来CursorAdapter让它工作,但是当我在构造函数中将 autoRequery 设置为 false 时,它的工作原理是一样的。当 autoRequery 设置为 false 时,为什么它会正确更新?

Am I using CursorAdaptercorrectly? What is the standard way of keeping the list updated with the database? And what does autoRequery do?

我使用CursorAdapter正确吗?使用数据库更新列表的标准方法是什么?autoRequery 有什么作用?

回答by Rich Schuler

The idiomatic and imho correct way to automatically update Cursors is to call Cursor#setNotificationUriwhen they are created and before they are handed off to whatever requested them. Then call ContentResolver#notifyChangewhen anything in that Cursor's Uri's namespace changes.

自动更新Cursors的惯用和恕我直言的正确方法Cursor#setNotificationUri是在创建它们时以及将它们移交给任何请求它们之前调用。然后ContentResolver#notifyChangeCursorUri 的命名空间中的任何内容发生更改时调用。

For example, suppose you were creating a simple mail application and you wanted to update when new mail arrived but also provide various views on the mail. I'd have some basic Uri's defined.

例如,假设您正在创建一个简单的邮件应用程序,并且您希望在新邮件到达时进行更新,同时还提供有关邮件的各种视图。我会定义一些基本的 Uri。

content://org.example/all_mail
content://org.example/labels
content://org.example/messages

Now, say I wanted to get a cursor that gave me all mail and be updated when new mail arrives:

现在,假设我想要一个光标,它给我所有的邮件,并在新邮件到达时更新:

Cursor c;
//code to get data
c.setNotificationUri(getContentResolver(), Uri.parse("content://org.example/all_mail");

Now new mail arrives so I notify:

现在新邮件到达,所以我通知:

//Do stuff to store in database
getContentResolver().notifyChange(Uri.parse("content://org.example/all_mail", null);

I should also notify all the Cursors that selected for labels this new message met

我还应该通知所有Cursor为标签选择的s 遇到了这条新消息

for(String label : message.getLabels() {
  getContentResolver().notifyChange(Uri.parse("content://org.example/lables/" + label, null);
}

And also, maybe a cursor is viewing that one specific message so notify them as well:

而且,也许光标正在查看该特定消息,因此也通知他们:

getContentResolver().notifyChange(Uri.parse("content://org.example/messages/" + message.getMessageId(), null);

The getContentResolver()calls happen where the data is accessed. So if it's in a Serviceor ContentProviderthat is where you setNotificationUriand notifyChange. You should not be doing that from where the data is accessed, e.g., an Activity.

getContentResolver()通话发生在数据被访问。因此,如果它在 aServiceContentProvider那是您setNotificationUrinotifyChange. 您不应该从访问数据的位置执行此操作,例如,Activity.

AlarmProvideris a simple ContentProviderthat uses this method to update Cursors.

AlarmProvider是一个简单的ContentProvider使用此方法更新Cursors 的方法。

回答by Anton Derevyanko

I created next method for ListView updating:

我为 ListView 更新创建了下一个方法:

/**
 * Method of refreshing Cursor, Adapter and ListView after database 
 * changing
 */
public void refreshListView() {
    databaseCursor = db.getReadableDatabase().query(
            CurrentTableName, 
            null, 
            null, 
            null, 
            null, 
            null, 
            "title"+SortingOrder);
    databaseListAdapter = new DomainAdapter(this, 
            android.R.layout.simple_list_item_2, 
            databaseCursor, 
            new String[] {"title", "description"}, 
            new int[] { android.R.id.text1, android.R.id.text2 });
    databaseListAdapter.notifyDataSetChanged();
    DomainView.setAdapter(databaseListAdapter);
}

end calls it each time after some changing in database

每次在数据库中进行一些更改后都会调用它