Как сохранить позицию ListView при использовании новых API Loader? - PullRequest
10 голосов
/ 28 августа 2011

В Honeycomb API-интерфейсы Loader были представлены как правильный способ предоставления данных приложению, выполняя тяжелую работу в фоновом потоке.В моем приложении я работаю над заменой всех моих Cursor с Loader с, которые возвращают Cursor с.Поскольку Cursor.requery() устарела, рекомендуется просто вызвать restartLoader и разрешить снова выполнить работу в фоновом потоке, а затем changeCursor, когда он вернется в onLoadFinished.

Всеэто прекрасно работает, за исключением того, что ListView не поддерживает свою позицию прокрутки, когда я хочу запросить данные, используя Cursor.requery(), это работало, потому что это был тот же экземпляр Cursor с обновленными данными.

Как я могу обновить мой загрузчик, не потеряв позицию прокрутки?

Ответы [ 2 ]

6 голосов
/ 28 августа 2011

Класс Loader сам по себе не знает, когда изменяется набор данных, и в настоящее время является реализацией, специфичной для CursorLoader.Теперь внутри моего приложения данные, которые мне нужно было обновить, находятся внутри локальной базы данных SQLite (без ContentProvider), поэтому мне пришлось изменить CursorLoader, чтобы вместо этого использовать мою локальную базу данных, как упомянула Дайан Хэкборн в группе разработчиков .

К сожалению, просто возвращение курсора из loadInBackground не позволяет ContentObserver должным образом уведомлять загрузчик при изменении данных, это потому, что AbstractCursor вызывает notifyChanged() только при вызове requery()Курсор.

Поскольку ContentObserver никогда не сообщит Loader, что данные изменились, я в конечном итоге сам вызвал Loader.onContentChanged() по мере необходимости.На данный момент все, кажется, работает, но я обновлю этот ответ, если возникнут какие-либо существенные проблемы.

1 голос
/ 16 февраля 2015

Вы просто не должны создавать новый адаптер при каждой загрузке Loaders; Я имею в виду ..

@Override
    public void onLoadFinished(Loader<List<NotificationItem>> loader, List<NotificationItem> notifications) {
        // We must do it in this way to not losing listview scroll position after a reload.
        if(mAdapter==null) {
            mAdapter = new HomeUserActivityListAdapter(getActivity(), notifications);
            mListView.setAdapter(mAdapter);

        }else{
            mAdapter.refill(notifications);
        }
    }

А в вашем адаптере создайте метод пополнения запасов

public void refill(List<NotificationItem> notifications) {
    mNotificationsList.clear();
    mNotificationsList.addAll(notifications);
    notifyDataSetChanged();
}

И это все, он точно сохранит вашу позицию прокрутки: -)

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