Matrixcursor с поставщиком контента, отличным от db

У меня есть поставщик контента, который возвращает MatrixCursor для метода query().

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

В методе обратного вызова onLoadFinished() LoaderManager я использую данные курсора для обновления текстового представления.

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?

Надеюсь, я ясно изложил вопрос. Заранее спасибо.


person shivagss    schedule 08.03.2014    source источник


Ответы (1)


Я надеюсь, что еще не слишком поздно или может кто-то еще может помочь.

Хитрая вещь здесь. Вам нужно создавать новый курсор каждый раз, когда вы запрашиваете contentProvider, по этой причине у меня есть список элементов, и каждый раз, когда я запрашиваю поставщика контента, я создаю новый курсор с моим поддерживаемым списком элементов, в котором есть новые элементы.

Почему я должен это делать? В противном случае вы получите исключение, потому что CursorLoader попытается зарегистрировать наблюдателя внутри курсора, у которого он уже есть. Обратите внимание, что способ создания новых строк в CursorMatrix разрешен на уровне API 19 и выше, но у вас есть альтернативные способы, но с более скучным кодом.

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;
}
person Xenione    schedule 19.03.2015
comment
Как это будет работать для метода обновления и удаления, если мы хотим использовать предложение выбора, чтобы обновить только один столбец и оставить остальные как есть? - person waseefakhtar; 18.05.2018