我有一个内容提供程序,它为query()方法返回MatrixCursor。
Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
{
MatrixCursor cursor = new MatrixCursor(new String[]{"a","b"});
cursor.addRow(new Object[]{"a1","b1"});
return cursor;
}
在LoaderManager的onLoadFinished()回调方法中,我使用游标数据来更新文本 View 。
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
cursor.moveToFirst();
String text = (String) textView.getText();
while (!cursor.isAfterLast()) {
text += cursor.getString(1);
cursor.moveToNext();
}
textView.setText(text);
}
现在的问题是,如何在MatrixCursor中添加新行,以将更改立即通知LoaderManager的回调方法?
希望我已经阐明了这个问题。提前致谢。
最佳答案
我希望还不算太晚,否则可能会有其他人可以帮助您。
棘手的事情在这里。出于这个原因,每次查询contentProvider时都必须创建一个新的游标,因为我有我的项目列表,而每次查询内容提供程序时,我都要使用包含新项目的支持项目列表来构建一个新的游标。
为什么我必须这样做?否则,由于CursorLoader试图在一个已经有一个游标的游标中注册一个观察者,您将得到一个异常。
请注意,在api级别19及更高版本中允许在CursorMatrix中构建新行的方法,但是您可以使用其他方法,但涉及更多令人讨厌的代码。
public class MyContentProvider extends ContentProvider {
List<Item> items = new ArrayList<Item>();
@Override
public boolean onCreate() {
// initial list of items
items.add(new Item("Coffe", 3f));
items.add(new Item("Coffe Latte", 3.5f));
items.add(new Item("Macchiato", 4f));
items.add(new Item("Frapuccion", 4.25f));
items.add(new Item("Te", 3f));
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
MatrixCursor cursor = new MatrixCursor(new String[] { "name", "price"});
for (Item item : items) {
RowBuilder builder = cursor.newRow();
builder.add("name", item.name);
builder.add("price", item.price);
}
cursor.setNotificationUri(getContext().getContentResolver(),uri);
return cursor;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
items.add(new Item(values.getAsString("name"),values.getAsFloat("price")))
//THE MAGIC COMES HERE !!!! when notify change and its observers registred make a requery so they are going to call query on the content provider and now we are going to get a new Cursor with the new item
getContext().getContentResolver().notifyChange(uri, null);
return uri;
}