Подтвердить что ты не робот

Android: как использовать CursorAdapter?

У меня есть база данных, ListView и CustomCursorAdapter, которая расширяет CursorAdapter. Кнопка меню добавляет элемент в базу данных. Я хочу, чтобы ListView обновлял и показывал это изменение. Обычно он не показывает этот новый элемент, пока я не перейду на рабочий стол и не открою приложение.

В конце концов я смог заставить его работать, вызывая cursor.requery() или mCustomCursorAdapter.changeCursor(newCursor) всякий раз, когда добавлял новый элемент, но когда я устанавливал autoRequery в false в конструкторе CursorAdapter, он работал точно так же. Почему он корректно обновляется, если для параметра autoRequery установлено значение false?

Правильно ли я использую CursorAdapter? Каков стандартный способ сохранения списка в базе данных? А что делает autoRequery?

4b9b3361

Ответ 1

Идиоматический и imho правильный способ автоматического обновления Cursor заключается в вызове Cursor#setNotificationUri, когда они созданы, и до их передачи к тому, что их просило. Затем вызовите ContentResolver#notifyChange, когда что-нибудь в этом пространстве имен Cursor Uri изменится.

Например, предположим, что вы создавали простое почтовое приложение, и вы хотели обновить его при поступлении новой почты, а также предоставить различные мнения по почте. Я бы определил некоторые основные Uri.

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

Теперь, скажем, я хотел получить курсор, который дал мне всю почту и обновиться при поступлении новой почты:

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

Теперь приходит новая почта, поэтому я уведомляю:

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

Я также должен уведомить все Cursor, которые выбраны для ярлыков, это новое сообщение встретило

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

А также, возможно, курсор просматривает это конкретное сообщение, также уведомляя об этом:

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

Звонки getContentResolver() происходят там, где доступны данные. Поэтому, если он находится в Service или ContentProvider, где вы setNotificationUri и notifyChange. Вы не должны делать этого, откуда доступны данные, например, Activity.

AlarmProvider - это простой ContentProvider, который использует этот метод для обновления Cursor s.

Ответ 2

Я создал следующий метод для обновления 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 вызывает его каждый раз после некоторого изменения базы данных