【问题标题】:Using Paging library with something other than a RecyclerView将分页库与 RecyclerView 以外的东西一起使用
【发布时间】: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


【解决方案1】:

使用标记聚类处理谷歌地图中大量点的显示 check android-maps-utils sample

【讨论】:

  • 我已经在使用集群渲染,但它不能很好地处理这些数量的地方(5k 使它非常慢),但这是一个渲染问题,而我正在谈论数据检索问题。
猜你喜欢
  • 2015-06-23
  • 2015-07-07
  • 2022-06-15
  • 2021-06-04
  • 2017-06-02
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
  • 2012-04-07
相关资源
最近更新 更多