Обновите SimpleCursorAdapter, сохранив позицию прокрутки в ListView

Моя проблема: My ListView сбрасывает свою позицию прокрутки вверх всякий раз, когда я обновляю его содержимое через его (настроенный) SimpleCursorAdapter. Я хотел бы, чтобы ListView сохранял свою позицию прокрутки при обновлении.

Я начал с того, что каждый раз создавал новый экземпляр адаптера и использовал ListView.setAdapter(), но согласно это обсуждение Я должен обновить адаптер, а не сбрасывать его. Я не могу найти способ сделать это для SimpleCursorAdapter, который работает правильно.

Вот некоторые вещи, которые я пробовал, опуская аргументы метода:
- SimpleCursorAdapter.changeCursorAndColumns() со свежим курсором успешно обновляет адаптер, но по-прежнему сбрасывает позицию прокрутки.
- SimpleCursorAdapter.changeCursor() действует таким же образом.
- SimpleCursorAdapter.swapCursor() isn не доступен до api 11, и я разрабатываю для api 8.
- SimpleCursorAdapter.notifyDataSetChanged() не обновляет ListView. (Возможно, мне не хватает еще одного шага.)
- ListView.invalidate() не обновляет ListView.
- SimpleCursorAdapter.requery() делает ListView пустым и не рекомендуется.
- Я знаком с решением ListView.setSelection(), но я не хочу, чтобы мой ListView вообще перемещался при обновлении. Это привяжет его к позиции в списке.

Кажется, это должна быть обычная и простая проблема. Кто-нибудь имел дело с этим?


person pvans    schedule 13.02.2012    source источник
comment
Смотрите мой комментарий под ответом. SimpleCursorAdapter.changeCursor () работает правильно - у меня просто была еще одна строка кода, которая все испортила.   -  person pvans    schedule 27.02.2012


Ответы (2)


У меня была аналогичная проблема: мой CursorAdapter сбрасывал позицию прокрутки при изменении содержимого курсора.

Я не понимал, что действительно устанавливал новый адаптер списка каждый раз, когда данные менялись. Я думал, что курсор сам будет уведомлять адаптер об изменениях его содержимого, но в моем случае это ContentProvider, который запускает LoaderManager.LoaderCallbacks.onLoadFinished () в моем ListFragment. В этом обратном вызове я теперь использую CursorAdapter.changeCursor () вместо создания нового адаптера, и все работает нормально.

Надеюсь, это поможет решить вашу проблему.

person Oderik    schedule 22.02.2012
comment
Оказывается, SimpleCursorAdapter.changeCursor () работает правильно. В моем случае причиной сброса позиции прокрутки списка была пара строк кода, вызываемых прямо перед изменением курсора: ListView.SetDivider() и ListView.SetDividerHeight. Действительно раздражает. У меня также есть строка ListView.setCacheColorHint(), которая не вызывает сброс позиции прокрутки. - person pvans; 27.02.2012

То же самое в пост-выполнении Async Task, использованного для меня, работал следующий код

 Cursor cursor = mDataHelper.getWritableDatabase().query(
                        DataContract.Incares.TABLE_NAME,  // Table to Query
                        null, // all columns
                        null, // Columns for the "where" clause
                        null, // Values for the "where" clause
                        null, // columns to group by
                        null, // columns to filter by row groups
                        DataContract.Incares.UUID +" DESC" // sort order
                );
CursorAdapter.changeCursor(cursor);
CursorAdapter.notifyDataSetChanged();

с CursorAdapter, являющимся глобальной переменной

person Amandeep Singh    schedule 19.07.2015
comment
Если у вас нет причины не закрывать старый курсор, используйте CursorAdapter.changeCursor(cursor), а не замену - person Renate; 16.03.2021