说实话,pagging的数据源定义是在是太繁琐了,所以二次封装了下,没有任何侵入,干净利落,暂时先留存下来,或许在我的生命之中还能用到。。
package com.lk.care.respository
import androidx.paging.DataSource
import androidx.paging.PageKeyedDataSource
import androidx.paging.PagedList
import androidx.paging.RxPagedListBuilder
import io.reactivex.schedulers.Schedulers
/**
* @author : william
* @createDate : 2020/5/28
*
* @description :
*/
abstract class PagingDataSourceFactory<K, V> : DataSource.Factory<K, V>() {
val cacheList = arrayListOf<V>()
override fun create() = createDataSource()
abstract fun createDataSource(): PageKeyedDataSource<K, V>
companion object {
fun <K, V> createRxPagedListBuilder(
setInitResult: (
params: PageKeyedDataSource.LoadInitialParams<K>,
callback: PageKeyedDataSource.LoadInitialCallback<K, V>
) -> Unit,
setAfterResult: (params: PageKeyedDataSource.LoadParams<K>, callback: PageKeyedDataSource.LoadCallback<K, V>) -> Unit,
vararg setBeforeResult: (params: PageKeyedDataSource.LoadParams<K>, callback: PageKeyedDataSource.LoadCallback<K, V>) -> Unit,
pageSize: Int = 20
) = RxPagedListBuilder(
object : PagingDataSourceFactory<K, V>() {
override fun createDataSource() = object : PageKeyedDataSource<K, V>() {
override fun loadInitial(
params: LoadInitialParams<K>,
callback: LoadInitialCallback<K, V>
) {
setInitResult.invoke(params, callback)
}
override fun loadAfter(params: LoadParams<K>, callback: LoadCallback<K, V>) {
setAfterResult.invoke(params, callback)
}
override fun loadBefore(params: LoadParams<K>, callback: LoadCallback<K, V>) {
if (setBeforeResult.isNotEmpty()) {
for (function in setBeforeResult) {
function.invoke(params, callback)
}
}
}
}
},
PagedList.Config.Builder()
.setPageSize(pageSize)
.setInitialLoadSizeHint(pageSize)
.build()
)
.setFetchScheduler(Schedulers.io())
.buildObservable()
}
}
我应该算是第一批尝试paging这个库的人之一吧,第一次尝鲜的时候就觉得这个库不行,这次的项目我突然想起这个库,就又拿出来练手玩,尤其是看过Android官方架构组件Paging:分页库的设计美学这篇文章之后,对这个库增加了更多的憧憬。 然而经过这次的大量使用后,着实坑了自己一把。现有感想如下:
-
首先使用起来真的太繁琐了,其实谷歌完全有能力简化它,比如基于我上面的写法,再加上枚举来生成不同的数据源(有点大言不惭了)但是几个版本下来,这个问题并没有改善。其次是还要再引入pageAdapter,而pageAdapter继承自ListAdapter,那么就限制了数据只能是List<>类型,也就把我喜欢使用的枚举排除在外了。如果想给列表加个header或者footer,我需要专门为h/f创建一个数据模型,还要在
submitList()
之前把数据模式插入到list中,这样又造成了加在下一页时要先去除footer等一系列问题,实在得不偿失。 -
这个库完全就是配合jetpack架构指南开发的,不能直观地动态修改item并刷新!!(pagedList竟然继承自abstractList,不能调用add、remove、set方法)虽然有多达几种方式去完成这种「普遍」操作,然而会严重破坏代码结构,得不偿失。最好的办法就是遵循jetpack架构指南,引入数据库做硬盘缓存,动态修改数据后硬缓存入数据库,并通过观察数据库自动完成UI刷新。但是这样一来,本来简单的一个纯网络动态获取数据的临时列表,就加入了数据库操作,每次启动我们都需要先清掉数据库缓存,再放入新数据,再刷新UI,增加了硬盘读写降低效率不说,一旦产品脑袋抽风,或者后端小伙子改了表字段,那就意味着我们需要对应的做数据库升级,重要数据也就算了,关键这只是临时列表啊!
-
无感刷新很棒,我们搞开发的都觉得很棒,但是。。。二逼产品经理就喜欢展示3秒钟的
loadingMore
,美名其曰:多一个交互就对用户多一份美好!此时咋办?
所以我觉得,paging确实是一个不错的玩意,代码很有思想。但是它毕竟不够灵活,局限实在太大,经不起多场景下的考验,鬼知道产品每天在想啥。
来源:oschina
链接:https://my.oschina.net/JiangTun/blog/4299494