【问题标题】:DataSource - Android Paging with dynamically growing listDataSource - 具有动态增长列表的 Android 分页
【发布时间】:2021-02-23 13:44:10
【问题描述】:

我正在尝试使用DataSource 实现以及PagedAdapter 在Android 上实现分页。

最初,要求是在内存中有一个完整的列表(不使用 RoomDB),我想在用户滚动时对该数据进行移动“视图” - 即将它提供给页面中的适配器。我通过使用PositionalDataSource 实现了这一点。

但是,现在我有一个新要求。原始完整列表中的一些项目实际上是“加载”项目(即微调器),我需要获取这些单元格以块的形式表示的数据。这些块的大小未确定。当一个块加载时,“正在加载”项应该在列表中向下移动,并且加载的块被插入到“正在加载”项所在的位置。这应该一直持续到“正在加载”项所代表的所有块都已加载完毕,此时应删除列表末尾的“正在加载”项。

这意味着,我的底层数据源实际上会随着用户滚动列表而动态增长。我认为这意味着 PositionalDataSource 不是用作源文档状态的正确数据源类型:

 * Position-based data loader for a fixed-size, countable data set, supporting fixed-size loads at
 * arbitrary page positions.

强调fixed-sizecountable - 显然我的数据集不是固定大小的(因此也是不可数的)。

我查看了DataSource 的其他实现,并认为我找到了正确的; ItemKeyedDataSource。我的每个项目确实都有一个唯一的键,并且此类的源文档指出:

 * Incremental data loader for paging keyed content, where loaded content uses previously loaded
 * items as input to future loads.

这对我来说表明我可以将它用于我所需的目的。 IE。当它需要在一个范围内加载具有给定键的项目(也恰好是“加载”项目)时,它可以使用加载项目数据来确定要加载的内容。

但是,我在实际实现时遇到了一些困难,因为官方文档没有给出任何真实的示例用法,并且示例代码的链接假定​​使用 RoomDB 或改造,这两种方法都不是我需要。

谁能帮助我概述一下这个 DataSource 应该如何在概念上和/或在代码示例中使用需要动态增长的内存数据集?

我意识到这很模糊,我今天早上才开始学习这门课,我很挣扎。

【问题讨论】:

    标签: android android-paging


    【解决方案1】:

    Paging 已经为您加载了分页数据 - 实现 DataSource 的目的是为 Paging 提供一种在用户滚动接近末尾时增量加载更多数据的方法。需要注意的是,在 Paging 2.x 中,加载状态未内置到库中,因此您需要自己跟踪它并使用诸如 ConcatAdapter 之类的方法显示微调器。

    如果您想尝试 v3 api(仍处于测试阶段),LoadState 是一个内置概念,您可以简单地使用.withLoadStateFooter() 转换将PagingDataAdapter 转换为ConcatAdapter,它会自动显示Paging 获取新页面时的加载微调器。

    为了澄清文档中有关计数快照的内容 - 分页使用单一事实来源 (DataSource / PagingSource),它应该代表一个静态列表(一旦完全加载)。这并不意味着您必须将整个列表保存在内存中,但DataSource 提取的每个实例通常应该与静态列表的心理模型相匹配。例如,如果您从 DB 中分页数据,则 DataSource / PagingSource 的单个实例仅在 DB 中没有更改时才有效。一旦您插入/修改/删除一行,该实例就不再有效,这就是 DataSource.Factory 发挥作用的地方,为您提供一个新的 PagedList / DataSource 对。

    现在,如果您还需要通过分层源方法增量更新支持数据集(本例中为 DB),Paging v2 提供了一个 BoundaryCallback,您可以注册以在 Paging 用完要加载的数据时触发网络提取,或者在v3 的新 API 是 RemoteMediator(仍处于试验阶段)。

    【讨论】:

    • 完美 - 我已经接受了这个答案。昨天我自己得出了同样的结论,并在我的“内存中”存储库中进行了一些棘手的操作,数据源遵循这些存储库,以便在加载内容时“随机”加载项目,并最终当它“用尽”时将其删除,每当我从内存存储库的底层添加/删除某些内容时,我都会通过回调使数据源无效,导致我的数据源工厂重新创建数据源(但内存存储库的底层仍然存在)。
    猜你喜欢
    • 1970-01-01
    • 2012-01-14
    • 2021-06-27
    • 2011-10-06
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多