android - 如何将 ContentObserver 与 RecyclerView 一起使用?

标签 android android-contentprovider android-recyclerview contentobserver

使用ListView,我们有一个很好的原生模式来将一些数据从数据库映射到列表:

DB -> ContentProvider -> CursorLoader -> CursorAdapter -> ListView

这种方法在数据层分离、性能和自动数据更新方面都很好。但是这种模式并不真正适合新的 RecyclerView。有一些方法可以模仿旧行为:

Using the recyclerview with a database

但是将旧式 notifyDataSetChangedRecyclerView 一起使用会出现问题。它不能使用 ItemAnimator 功能,它失去了滚动位置,而且它只是无效的。

那么,在使用包含在 ContentProvider 中的数据库时,我们如何才能从细粒度的更改通知中获益? Cursor 是静态的,要从中获取新数据,我们需要获取新的 Cursor。因此,我们似乎需要一个自定义的中间数据层,它将合并来自 Cursors 的数据并将实体的 List 暴露给 RecyclerView.Adapter。此外,我们必须手动将 ContentObserver onChange() 事件映射到 RecyclerView 通知。这也意味着我们将不得不摆脱 CursorLoader。对于这样的基本任务,这是难以置信的工作量。

有没有更好的解决方案?

最佳答案

您可以使用 DiffUtils类来计算新旧游标之间的差异。

使用它时你只需要实现两个方法:

  • areItemsTheSame() 了解两个项目是否表示相同的逻辑项目(即使内容不同)。通常,您会根据项目的标识字段来回答;
  • areContentsTheSame() 了解表示同一逻辑项目的两个项目是否具有未修改的内容。

一旦计算出差异,您就可以将它应用到您的适配器,它会自动调用 notifyItemChanged()notifyItemInserted()notifyItemRemoved () 相应地。

关于android - 如何将 ContentObserver 与 RecyclerView 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29844705/

相关文章:

android - 从内容提供者返回内存映射的 InputStream?

android - 如何使 FileProvider 为可绘制对象提供服务?

android - PhoneLookup.CONTENT_FILTER_URI,总是返回空结果

android - 回收站 View 适配器中的选项菜单

java - Android Paging Library如何知道加载更多数据?

Android 可浏览 Intent 在 gmail 链接上失败,但适用于默认邮件客户端

android - Android Studio 可以在新类(class)开始时生成 TAG 吗?

java - 使用 Recyclerview 和 Volley 无法在 fragment 中工作

android - ImageView 有过多的垂直填充

java - 单元测试Android功能