Android: как использовать CursorAdapter? - PullRequest
16 голосов
/ 23 августа 2010

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

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

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

Ответы [ 2 ]

37 голосов
/ 23 августа 2010

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

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

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 s, которые выбрали для ярлыков это новое сообщение встретил

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 с.

1 голос
/ 12 октября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...