使用新的 Loader API 时如何保持 ListView 位置?

发布于 2024-12-01 18:26:52 字数 541 浏览 2 评论 0原文

在 Honeycomb 中,引入了 Loader API,作为向应用程序提供数据的正确方法,方法是执行以下操作:后台线程的繁重工作。在我的应用程序中,我正在努力将所有 Cursor 替换为返回 CursorLoader。由于 Cursor.requery() 现已弃用,建议仅调用 restartLoader 并允许在后台线程上再次完成工作,然后 changeCursor< /code> 当它在 onLoadFinished 中返回时。

所有这些都工作得很好,除了当我想重新查询数据时,ListView 不保持其滚动位置,使用 Cursor.requery() 这曾经可以工作,因为它是更新后的同一个 Cursor 实例数据。

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

In Honeycomb the Loader APIs were introduced as the proper way to provide data to an application by doing the heavy lifting on a background thread. In my application I'm working to replace all my Cursors with Loaders that return Cursors. Since Cursor.requery() is depreciated now, it is recommended to just call restartLoader and allow the work to again be done on a background thread and then changeCursor when it returns in onLoadFinished.

All of this works wonderfully except that the ListView doesn't maintain it's scroll position when I want to requery the data, using Cursor.requery() this used to work because it was the same Cursor instance with updated data.

How can I refresh my Loader without loosing the scroll position?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

山色无中 2024-12-08 18:26:52

Loader 类本身不知道数据集何时更改,并且当前是特定于 CursorLoader 的实现。现在,在我的应用程序中,我需要刷新的数据位于本地 SQLite 数据库(无 ContentProvider)中,因此我必须修改 CursorLoader 以使用我的本地数据库,正如 Dianne Hackborne 在 开发者小组

不幸的是,仅仅从 loadInBackground 返回 Cursor 并不允许 ContentObserver 在数据更改时正确通知 Loader,这是因为 AbstractCursor 仅调用 notifyChanged()< /code> 当在 Cursor 上调用 requery() 时。

由于 ContentObserver 永远不会通知 Loader 数据已更改,因此我最终根据需要自己调用 Loader.onContentChanged() 。此时一切似乎都正常,但如果出现任何重大问题,我将更新此答案。

The Loader class by itself doesn't know when the dataset changes and is implementation specific to CursorLoader currently. Now inside my application the data I needed to refresh is inside a local SQLite database (no ContentProvider) so I had to modify the CursorLoader to use my local database instead, as Dianne Hackborne mentioned on the developer group.

Unfortunately just returning a Cursor from loadInBackground doesn't allow the ContentObserver to properly notify the Loader when the data changes, this is because AbstractCursor only calls notifyChanged() when requery() is called on the Cursor.

Since the ContentObserver will never notify the Loader that the data has changed, I ended up calling Loader.onContentChanged() myself as needed. At this point it everything seems to be working but I'll update this answer if any significant issues arrise.

酒儿 2024-12-08 18:26:52

你一定不要在每次加载器加载时创建一个新的适配器;我的意思是..

@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();
}

仅此而已,它将准确地保持您的滚动位置:-)

You must just do not create a new adapter in each Loaders loading; I mean..

@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);
        }
    }

And in you adapter create a method to items refill

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

And that's all, it will maintain your scroll position exactly :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文