/**
* PagingSource 通用封装类
*/
class IntKeyPagingSource<S : BaseService, V : Any>(
private val pageStart: Int = BaseService.DEFAULT_PAGE_START_NO_1,
private val service: S,
private val load: suspend (S, Int, Int) -> List<V>
) : PagingSource<Int, V>() {
override fun getRefreshKey(state: PagingState<Int, V>): Int? {
// return state.anchorPosition?.let { anchorPosition ->
// state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
// ?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
// }
return null
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, V> {
val page = params.key ?: pageStart
return try {
val data = load(service, page, params.loadSize)
LoadResult.Page(
data = data,
prevKey = if (page == pageStart) null else page - 1,
nextKey = if (data.isEmpty()) null else page + 1
)
} catch (e: Exception) {
LoadResult.Error(e)
}
}
}
interface BaseService {//设计一个通用的Api----Service
companion object {
/**
* 默认初始页数
*/
const val DEFAULT_PAGE_START_NO = 0
const val DEFAULT_PAGE_START_NO_1 = 1
}
}
interface ProjectService : BaseService {
/**
* 最新项目列表
*/
@GET("article/listproject/{pageNo}/json")
suspend fun getNewProjectPageList(
@Path("pageNo") pageNo: Int,
@Query("page_size") pageSize: Int
): NetworkResponse<PageResponse<Article>>
}
private val service by lazy {
RetrofitManager.getService(ProjectService::class.java)
}
下面的BaseViewModel:
abstract class BaseViewModel : ViewModel() {
companion object {
const val DEFAULT_PAGE_SIZE = 20
}
inline fun <reified T : Any> getPagingSourceFlow(
service: BaseService, crossinline request: suspend (Int, Int) -> List<T>
) = Pager(
PagingConfig(
pageSize = DEFAULT_PAGE_SIZE,
initialLoadSize = DEFAULT_PAGE_SIZE,
enablePlaceholders = false
)
) {
IntKeyPagingSource(service = service) { _, page, size ->
request(page, size)
}
}.flow
}
------------------------------------分割线----------------------
后面是使用:
class ProjectViewModel:BaseViewModel (){
/**
* 最新项目列表Flow
*/
fun getNewProjectListFlow2() = getPagingSourceFlow(service) { page, size ->
service.getNewProjectPageList(page, size).getOrNull()?.datas ?: emptyList()
}//直接返回paging3的flow,一行代码解决,简单好用。
}
projectViewModel.getNewProjectListFlow2().collectLatest {
appStorePagingAdapter.submitData(it)
}//提交数据到 PagingAdapter
经过了上面的封装,paging3 简单又好用,一行代码解决问题。