10

在 Honeycomb 中,Loader API 被引入作为通过在后台线程上执行繁重的工作来向应用程序提供数据的正确方法。在我的应用程序中,我正在努力用返回s 的 s 替换我Cursor的所有s。由于现在已贬值,因此建议只调用并允许在后台线程上再次完成工作,然后当它返回时。LoaderCursorCursor.requery()restartLoaderchangeCursoronLoadFinished

除了 ListView 在我想重新查询数据时不保持其滚动位置之外,所有这些都非常Cursor.requery()有效,因为它是具有更新数据的相同 Cursor 实例,所以使用它曾经可以工作。

如何在不丢失滚动位置的情况下刷新加载程序?

4

2 回答 2

6

该类Loader本身不知道数据集何时更改并且是特定于CursorLoader当前的实现。现在在我的应用程序中,我需要刷新的数据在本地 SQLite 数据库(没有 ContentProvider)中,所以我不得不修改它CursorLoader以使用我的本地数据库,正如 Dianne Hackborne 在开发人员组中提到的那样。

不幸的是,仅从 loadInBackground 返回一个 Cursor 并不允许ContentObserver在数据更改时正确通知 Loader,这是因为AbstractCursor只有在 Cursor 上调用notifyChanged()时才调用。requery()

由于ContentObserver将永远不会通知Loader数据已更改,因此我最终根据需要给自己打电话Loader.onContentChanged()。在这一点上,一切似乎都在工作,但如果出现任何重大问题,我会更新这个答案。

于 2011-08-28T08:12:21.347 回答
1

您必须不要在每个 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();
}

仅此而已,它将完全保持您的滚动位置:-)

于 2015-02-16T10:21:36.570 回答