記得應(yīng)該是2.0版本的時(shí)候開始使用paging這個分頁框架。
但是說老實(shí)話,我要實(shí)現(xiàn)分頁德華,首先必須寫一大坨代碼,繞來繞去的。無論怎么封裝,代碼量都不會少。
分層是狗清晰了。但是,目前大家都這么忙,無法實(shí)現(xiàn)開箱即用。實(shí)在是無法堅(jiān)持使用下去。
所以,放棄了。
聽說更新了3.0版本,目前最新版是3.0.0-alpha09。
看了一下,還是有一些變化的。那就繼續(xù)使用看看吧。
再BB一句:寫完一個功能并不算好用,你能把它用在幾個功能,并且有得心應(yīng)手的感覺,那才是好用!
1.什么也別說,先干pagingSrouce
假設(shè)我們的分頁數(shù)據(jù)是pageNow和pagesize的形式。當(dāng)然你的也可以start和 end的方式。
那么這個時(shí)候,我們的代碼應(yīng)該是
class FencePagingSource : PagingSource<Int, PageBean<Geofence>>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, PageBean<Geofence>> {
//不要問Int是什么。你高興傳入一個String,然后慢慢轉(zhuǎn)成Int也可以~
//也不要問Geofence 是什么。只穿返回額實(shí)體類,不要寫list<Geofence >
}
}
然后在load里面寫你自己的邏輯。
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, PageBean<Geofence>> {
return try {
val pageNow = params.key ?: 1
val pageSize = params.loadSize
val map = HashMap<String, Any>();
map["pageNow"] = pageNow
map["pageSize"] = pageSize
val response = GeoFenceApi.create().getEctricFenceList(map);//同步返回結(jié)果
LoadResult.Page(
data = response.data,
prevKey = if (pageNow == 1) null else pageNow - 1,
nextKey = if (response.isLastPage()) null else pageNow + 1
)
} catch (e: Exception) {
LoadResult.Error(e)
}
}
2.編寫Pager
//Flow<PagingData<Geofence>>
//pagingconfig 是頁面大小和距離多少就開始加載下一個的配置項(xiàng)。和以前2.0版本的一樣
val pager=Pager(PagingConfig(30, 3)){FencePagingSource()}.flow
3.編寫adapter
先從簡單的開始。假設(shè)沒有頭部文件吧。
自己的adapter必須要繼承PagingDataAdapter
//BaseViewHolder是自己封裝的
class FenceAdapter() : PagingDataAdapter<Geofence, BaseViewHolder<Geofence>>(
diffCallback
) {
companion object {
val diffCallback = object : DiffUtil.ItemCallback<Geofence>() {
override fun areItemsTheSame(oldItem: Geofence, newItem: Geofence): Boolean {
}
override fun areContentsTheSame(oldItem: Geofence, newItem: Geofence): Boolean {
}
}
}
override fun onBindViewHolder(holder: BaseViewHolder<Geofence>, position: Int) {
//綁定數(shù)據(jù)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<Geofence> {
//創(chuàng)建holder
}
}
/** diffCallback是判斷兩個item是否相同。一般來說用主鍵,也就是唯一性去判斷
所以,上面的diffCallback 又可以寫成 **/
val diffCallback = object : DiffUtil.ItemCallback<Geofence>() {
override fun areItemsTheSame(oldItem: Geofence, newItem: Geofence): Boolean {
return newItem.id == oldItem.id
}
override fun areContentsTheSame(oldItem: Geofence, newItem: Geofence): Boolean {
return newItem.id == oldItem.id
}
}
5 編寫viewmodel
定義一個livedata,用于給前臺進(jìn)行訂閱處理。同時(shí)接收剛才在上面定義的pager
假設(shè)我們有一個倉庫類。repository。
override fun queryFenceList(): Flow<PagingData<GeoFence>> {
return Pager(PagingConfig(30, 3)){FencePagingSource()}.flow
}
那么viewmodel里面的代碼就是
val liveData=repository.queryFenceList().asLiveData()
6.activity訂閱數(shù)據(jù)和顯示UI
viewModel.liveData.observe(this) {
lifecycleScope.launchWhenCreated {
adapter.submitData(lifecycle, it)
}
}
當(dāng)然,不要那么憨憨,adapter記得初始化和recycleView關(guān)聯(lián)起來。
到此,初步使用就結(jié)束了。下一篇文章寫的是刷新重試,加載中,加載完成這些惡心的東西。