class DataSource():PagingSource<Int,DemoReqData.DataBean.DatasBean>(){
override suspend fun load(params: LoadParams): LoadResult<Int, DemoReqData.DataBean.DatasBean> {
TODO(“Not yet implemented”)
}
}
我们可以看到PagingSource中有两个参数Key 和 Value,这里Key我们定义为Int类型Value DemoReqData 是接口返回数据对应的实体类,这里的意思就是
我们传Int类型的值(如页码)得到返回的数据信息DemoReqData对象。
这里需要提醒的是如果你使用的不是Kotlin 协程而是Java,则需要继承对应的PagingSource如RxPagingSource或ListenableFuturePagingSource。
DataSource为我们自动生成了load方法,我们主要的请求操作就在load方法中完成。主要代码如下所示:
override suspend fun load(params: LoadParams): LoadResult<Int, DemoReqData.DataBean.DatasBean> {
return try {
//页码未定义置为1
var currentPage = params.key ?: 1
//仓库层请求数据
var demoReqData = DataRespority().loadData(currentPage)
//当前页码 小于 总页码 页面加1
var nextPage = if (currentPage < demoReqData?.data?.pageCount ?: 0) {
currentPage + 1
} else {
//没有更多数据
null
}
if (demoReqData != null) {
LoadResult.Page(
data = demoReqData.data.datas,
prevKey = null,
nextKey = nextPage
)
} else {
LoadResult.Error(throwable = Throwable())
}
} catch (e: Exception) {
LoadResult.Error(throwable = e)
}
}
上面代码我们可以看到在datasource中我们通过DataRespority()仓库层,去请求数据,如果没有更多数据就返回null,最后使用 LoadResult.Page将结果返回,如果加载失败则用LoadResult.Error返回,由于 LoadResult.Page中的data 必须是非空类型的,所以我们需要判断返回是否为null。
接下来我们看下DataRespority仓库层的代码,代码比较简单,如下所示:
class DataRespority {
private var netWork = RetrofitService.createService(
DataApi::class.java
)
/**
- 查询护理数据
*/
suspend fun loadData(
pageId: Int
): DemoReqData? {
return try {
netWork.getData(pageId)
} catch (e: Exception) {
//在这里处理或捕获异常
null
}
}
}
Load调用官方给出的流程如下所示:
从上图可以知道,load的方法 是我们通过Paging的配置自动触发的,不需要我们每次去调用,那么我们如何来使用DataSource呢?
调用PagingSource
The Pager
object calls the load()
method from the PagingSource
object, providing it with the LoadParams object and receiving the LoadResult object in return.
这句话翻译过来的意思就是:Pager对象从PagingSource对象调用load()方法,为它提供LoadParams对象,并作为回报接收LoadResult对象。
所以我们在创建viewModel对象,并创建pager对象从而调用PagingSource方法 ,代码如下所示:
class MainActivityViewModel : ViewModel() {
/**
- 获取数据
*/
fun getData() = Pager(PagingConfig(pageSize = 1)) {
DataSource()
}.flow
}
在viewmodel中我们定义了一个getData的方法,Pager中通过配置PagingConfig来实现特殊的定制,我们来看下PagingConfig中的参数如下:
pageSize:定义从 PagingSource 一次加载的项目数。
prefetchDistance:预取距离,简单解释就是 当距离底部还有多远的时候自动加载下一页,即自动调用load方法,默认值和pageSize相等
enablePlaceholders:是否显示占位符&