android-调页库-具有API占用页面和siz的网络+ db的边界回调
简短问题:
使用使用页面+大小加载新页面的API和PagedKeyedDatasource类的API,从架构组件处理分页库上的数据库+网络的正确方法是什么?
研究与解释
当前,用于体系结构组件的分页库中使用的类PagedKeyedDatasource接收列表中元素的实例作为参数,而没有该元素所在位置的实际上下文。 它发生在PagedKeyedDatasource和onItemAtEndLoaded中。
我的Api应该接收页面和页面大小以加载下一个数据块。 作为分页列表构建器的一部分添加的边界回调应根据预取距离和页面大小告诉您何时加载下一页数据。
由于Api需要页面号和页面大小才能提供,因此我没有看到一种仅通过接收PagedKeyedDatasource和onItemAtEndLoaded中提供的列表中的元素之一就将其发送给Api的方法。 在此链接中,他们使用最后一个元素的名称来获取下一个元素,但这不适合页面+大小的Api。
他们也有一个仅使用PagedKeyedDatasource的网络的示例,但是没有关于如何将其与数据库和BoundaryCallback混合使用的示例或线索。
编辑:到目前为止,我发现的唯一解决方案是将最后加载的页面存储在共享首选项上,但这听起来像是一个肮脏的把戏。
参考[https://github.com/googlesamples/android-architecture-components/issues/252#issuecomment-392119468]以获得官方意见。
3个解决方案
1 votes
我实现了这一点:
PagedList.BoundaryCallback boundaryCallbackNovidades = new PagedList.BoundaryCallback(){
int proxPagina;
boolean jaAtualizouInicio=false;
public void onZeroItemsLoaded() {
requestProdutos(
webService.pesquisarNovidadesDepoisDe(LocalDateTime.now().format(Util.formatterDataTime), 0, 20));
}
public void onItemAtFrontLoaded(@NonNull Produto itemAtFront) {
if(!jaAtualizouInicio)
requestProdutos(
webService.pesquisarNovidadesMaisRecentesQue(itemAtFront.data.format(Util.formatterDataTime)));
jaAtualizouInicio=true;
}
public void onItemAtEndLoaded(@NonNull Produto itemAtEnd) {
requestProdutos(
webService.pesquisarNovidadesDepoisDe(LocalDateTime.now().format(Util.formatterDataTime), proxPagina++, 20));
}
};
public LiveData> getNovidades(){
if(novidades==null){
novidades = new LivePagedListBuilder<>(produtoDao.produtosNovidades(),
10)
.setBoundaryCallback(boundaryCallbackNovidades)
.build();
}
return novidades;
}
user3795295 answered 2019-11-14T12:35:42Z
0 votes
假设您总是从服务器每页获取N=10个项目,然后将其存储在db中。 您可以使用sql查询SELECT COUNT(*) FROM tbl获取db中的项目数,并将其存储在变量count中。现在,获取下一步应请求的页码,请使用:
val nextPage: Int = (count / N) + 1
realpac answered 2019-11-14T12:36:08Z
0 votes
文档对此有此说法:
如果您不使用项目键网络API,则可能是在使用 页面键控或页面索引。 如果是这种情况,则分页库 不知道BoundaryCallback中使用的页面键或索引, 因此您需要自己进行跟踪。 您可以通过以下两种方式之一执行此操作:
本地存储页面键
如果您想完美地恢复查询, 即使应用程序被终止并恢复,您也可以将密钥存储在磁盘上。 请注意,使用位置/页面索引网络API,有一个简单的方法 使用listSize作为下一次加载的输入的方法(或 listSize / NETWORK_PAGE_SIZE,用于页面索引)。 当前清单 大小不会传递给BoundaryCallback。 这是因为 PagedList不一定知道本地项的数量 存储。 占位符可能被禁用,或者数据源可能不计数 项目总数。
相反,对于这些位置情况,您可以查询数据库以获取 项目数量,并将其传递给网络。
内存页面键
通常,查询下一页没有意义 如果您获取的最后一页已加载多个小时,则来自网络 前几天。 如果将密钥保留在内存中,则可以随时刷新 您从网络源开始分页。 将下一个密钥存储在内存中, 在您的BoundaryCallback中。 当您创建一个新的BoundaryCallback时 创建新的LiveData / Observable of PagedList时,刷新数据。 例如,在Paging Codelab中,GitHub网络页面索引为 存储在内存中。
并链接到示例代码实验室:[https://codelabs.developers.google.com/codelabs/android-paging/index.html#8]
Luke answered 2019-11-14T12:37:28Z