短问题
使用使用页面+大小加载新页面和BoundaryCallback
类的API,从体系结构组件中处理分页库上的数据库+网络的正确方法是什么?
研究与解释
当前,用于体系结构组件的分页库中使用的类BoundaryCallback
作为参数接收列表中元素的实例,而没有该元素所在位置的实际上下文。这种情况发生在onItemAtFrontLoaded
和onItemAtEndLoaded
中。
我的Api应该接收页面和页面大小来加载下一个数据块。边界回调作为分页列表构建器的一部分添加,用于根据预取距离和页面大小告诉您何时加载下一页数据。
由于Api需要提供页面号和页面大小,所以我无法通过接收onItemAtFrontLoaded
和onItemAtEndLoaded
中提供的列表中的一个元素将其发送给Api。检查此链接中的google示例,它们使用最后一个元素的名称来获得下一个元素,但这不适合带有页面+大小的Api。
他们还有另外一个例子,即只使用PagedKeyedDatasource
的网络,但是对于如何将其与数据库和BoundaryCallback混合使用,没有任何示例或线索。
编辑:到目前为止,我找到的唯一解决方案是将最后加载的页面存储在共享首选项上,但这听起来很脏。
有关它的官方输入,请参考https://github.com/googlesamples/android-architecture-components/issues/252#issuecomment-392119468。
发布于 2019-07-03 13:46:58
在这个问题上,文档有这样一个说法:
如果您没有使用项键网络API,则可能使用页键或页索引。如果是这样的话,分页库不知道BoundaryCallback中使用的页面键或索引,所以需要自己跟踪它。您可以通过以下两种方式之一进行此操作: 本地存储页密钥 如果你想完全恢复你的查询,即使应用程序被杀死并恢复,你也可以将密钥存储在磁盘上。注意,使用位置/页面索引网络API,有一种简单的方法可以做到这一点,方法是使用listSize作为下一个加载的输入(或listSize / NETWORK_PAGE_SIZE,用于页面索引)。但是,当前的列表大小没有传递给BoundaryCallback。这是因为PagedList不一定知道本地存储中的项目数。占位符可能被禁用,或者DataSource可能不计算项目总数。 相反,对于这些位置情况,您可以查询数据库中的项目数,并将其传递给网络。 内存页键 通常,如果您获取的最后一页是在多小时或几天前加载的,那么从网络查询下一页就没有意义了。如果将密钥保存在内存中,则可以在从网络源开始分页时随时刷新。将下一个键存储在内存中,存储在BoundaryCallback中。当您在创建新的LiveData/可观察到的BoundaryCallback时创建一个新的PagedList,刷新数据。例如,在寻呼Codelab中,GitHub网络页索引存储在内存中。
以及指向Codelab示例的链接:https://codelabs.developers.google.com/codelabs/android-paging/index.html#8
发布于 2020-05-17 07:19:48
我有一个类似的API (pageNum + size),在我的data class
、pageNum
和pageSize
中有两个额外的字段,分别是默认的1
和PAGE_SIZE
。
如果您使用的是Network+DB
,那么您将在onZeroItemsLoaded
、send、pageNum
和pageSize
中使用onZeroItemsLoaded
和onItemAtEndLoaded
,在onItemAtEndLoaded
增量pageSize中使用1
,然后再发送。
假设您有一个方法fetchData(pageNum, pageSize)
,当收到结果时,只需在此页面的每个项中相应地更新pageNum
和pageSize
。
发布于 2018-12-28 00:13:52
我执行这一规定:
PagedList.BoundaryCallback<Produto> boundaryCallbackNovidades = new PagedList.BoundaryCallback<Produto>(){
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<PagedList<Produto>> getNovidades(){
if(novidades==null){
novidades = new LivePagedListBuilder<>(produtoDao.produtosNovidades(),
10)
.setBoundaryCallback(boundaryCallbackNovidades)
.build();
}
return novidades;
}
https://stackoverflow.com/questions/50456919
复制相似问题