【发布时间】:2019-09-17 10:55:21
【问题描述】:
我有一个包含大约 5000 个“地点”(即要在地图上显示的纬度和经度)的数据库,我希望能够在地图上显示它们。
现在从 Room 一次性检索 5000 个地点给我带来了麻烦(超过了 this question 中所述的大小限制),所以我想使用分页库检索大约 100 个批次并慢慢填充地图.
然而,Jetpack 附带的 Paging 库似乎非常倾向于将它与 RecyclerView 一起使用,整个 documentation 围绕着构建一个无限滚动的 recyclerview。
所以我想知道是否可以将它与自定义组件一起使用,而不是仅与文档中所述的 PagedAdapter 一起使用。他们提到AsyncPagedListDiffer 有这个签名:
AsyncPagedListDiffer(ListUpdateCallback listUpdateCallback, AsyncDifferConfig<T> config)
所以我继续尝试这样实现:
道:
@Query("SELECT * FROM places join list_results where places.placeId = list_results.id ORDER by placeName ASC")
abstract fun getFilteredPlacesPaginated(): DataSource.Factory<Int, PlaceVO>
存储库:
override fun getListPlaces(pageSize: Int, boundaryCallback: PagedList.BoundaryCallback<StateAwarePlace>): Flowable<PagedList<StateAwarePlace>> {
return placesDao.getFilteredPlacesPaginated().map { StateAwarePlace.state(it) }.toFlowable(pageSize = pageSize, boundaryCallback = boundaryCallback)
}
视图模型:
val boundaryCallback: PagedList.BoundaryCallback<StateAwarePlace> = object : PagedList.BoundaryCallback<StateAwarePlace>() {
override fun onZeroItemsLoaded() {
super.onZeroItemsLoaded()
Timber.w("PAGINATEDLIST - OnZeroItemsLoaded")
}
override fun onItemAtEndLoaded(itemAtEnd: StateAwarePlace) {
super.onItemAtEndLoaded(itemAtEnd)
Timber.w("PAGINATEDLIST - onItemAtEndLoaded ${itemAtEnd.place.placeName}")
}
override fun onItemAtFrontLoaded(itemAtFront: StateAwarePlace) {
super.onItemAtFrontLoaded(itemAtFront)
Timber.w("PAGINATEDLIST - onItemAtFrontLoaded ${itemAtFront.place.placeName}")
}
}
val paginatedPlaces = placesRepository.getListPlaces(50, boundaryCallback).toLiveData()
片段:
val asyncPagedListDiffer = AsyncPagedListDiffer<StateAwarePlace>(object : ListUpdateCallback {
override fun onChanged(position: Int, count: Int, payload: Any?) {
Timber.w("PAGINATEDLIST - Item in position $position has changed, now count is $count, payload $payload")
}
override fun onMoved(fromPosition: Int, toPosition: Int) {
Timber.d("PAGINATEDLIST - Item moved from $fromPosition to $toPosition")
}
override fun onInserted(position: Int, count: Int) {
Timber.i("PAGINATEDLIST - Item inserted on position $position, new count is $count")
}
override fun onRemoved(position: Int, count: Int) {
Timber.v("PAGINATEDLIST - Item removed on position $position, count is $count")
}
}, PlacesPaginatedAdapter.asyncConfig);
viewModel.paginatedPlaces.observe(this) { placesList: PagedList<StateAwarePlace> ->
asyncPagedListDiffer.submitList(placesList)
asyncPagedListDiffer.addPagedListListener { previousList, currentList ->
Timber.w("PAGINATEDLIST - Paged list listener ${previousList?.size} to ${currentList?.size}")
}
}
但它似乎总是加载总数量的地方。
我也不知道如何告诉 pagedlist 检索更多页面,或者如何使用差异将数据发送到我的地图实例...
toFlowable:
fun <Key, Value> DataSource.Factory<Key, Value>.toFlowable(
pageSize: Int,
initialLoadKey: Key? = null,
boundaryCallback: PagedList.BoundaryCallback<Value>? = null,
fetchScheduler: Scheduler? = null,
notifyScheduler: Scheduler? = null,
backpressureStrategy: BackpressureStrategy = BackpressureStrategy.LATEST
): Flowable<PagedList<Value>> {
return createRxPagedListBuilder(
dataSourceFactory = this,
config = Config(pageSize),
initialLoadKey = initialLoadKey,
boundaryCallback = boundaryCallback,
fetchScheduler = fetchScheduler,
notifyScheduler = notifyScheduler).buildFlowable(backpressureStrategy)
}
private fun <Key, Value> createRxPagedListBuilder(
dataSourceFactory: DataSource.Factory<Key, Value>,
config: PagedList.Config,
initialLoadKey: Key?,
boundaryCallback: PagedList.BoundaryCallback<Value>?,
fetchScheduler: Scheduler?,
notifyScheduler: Scheduler?
): RxPagedListBuilder<Key, Value> {
val builder = RxPagedListBuilder(dataSourceFactory, config)
.setInitialLoadKey(initialLoadKey)
.setBoundaryCallback(boundaryCallback)
if (fetchScheduler != null) builder.setFetchScheduler(fetchScheduler)
if (notifyScheduler != null) builder.setNotifyScheduler(notifyScheduler)
return builder
}
【问题讨论】:
-
见
LivePagedListBuilder(或PagedListBuilder) -
@pskink 这是我通过 toFlowable 扩展使用的(检查已编辑的问题)
-
仍然不知道如何请求更多页面:(
-
你必须调用
build()并且当你有PagedList对象时,只需使用loadAround()/get()方法,如果仍然不确定,请参阅PagedListAdapterHelper.java源文件并检查mList字段和在哪里使用它 - PagedList 官方文档说:“PagedList 是一个列表,它从 DataSource 以块(页面)的形式加载其数据。可以使用 get(int) 访问项目,并且可以触发进一步的加载使用 loadAround(int)。” -
@pskink 这确实有效,谢谢。
标签: android android-recyclerview android-room android-paging