我尝试使用 Paging 3 库实现分页。为此,我在Requests
课堂上创建了假请求:
fun getBerubyMerchantsByFilter(body: BerubyMerchantsByFilterRequest) = Single.just(
BerubyMerchantsByFilterResponse(
merchants = mutableListOf(
BerubiExclusiveOfferResponse(
(body.page ?: 0) * 11 + 1,
"name",
"category",
1,
"cashback",
"https://www.lomsnesvet.ca/wp-content/uploads/sites/21/2019/08/Kitten-Blog-683x1024.jpg"
),
BerubiExclusiveOfferResponse(
(body.page ?: 0) * 11 + 2,
"name",
"category",
1,
"cashback",
"https://www.lomsnesvet.ca/wp-content/uploads/sites/21/2019/08/Kitten-Blog-683x1024.jpg"
),
BerubiExclusiveOfferResponse(
(body.page ?: 0) * 11 + 3,
"name",
"category",
1,
"cashback",
"https://www.lomsnesvet.ca/wp-content/uploads/sites/21/2019/08/Kitten-Blog-683x1024.jpg"
),
BerubiExclusiveOfferResponse(
(body.page ?: 0) * 5 + 4,
"name",
"category",
1,
"cashback",
"https://www.lomsnesvet.ca/wp-content/uploads/sites/21/2019/08/Kitten-Blog-683x1024.jpg"
),
BerubiExclusiveOfferResponse(
(body.page ?: 0) * 11 + 5,
"name",
"category",
1,
"cashback",
"https://www.lomsnesvet.ca/wp-content/uploads/sites/21/2019/08/Kitten-Blog-683x1024.jpg"
),
BerubiExclusiveOfferResponse(
(body.page ?: 0) * 11 + 6,
"name",
"category",
1,
"cashback",
"https://www.lomsnesvet.ca/wp-content/uploads/sites/21/2019/08/Kitten-Blog-683x1024.jpg"
),
BerubiExclusiveOfferResponse(
(body.page ?: 0) * 11 + 7,
"name",
"category",
1,
"cashback",
"https://www.lomsnesvet.ca/wp-content/uploads/sites/21/2019/08/Kitten-Blog-683x1024.jpg"
),
BerubiExclusiveOfferResponse(
(body.page ?: 0) * 11 + 8,
"name",
"category",
1,
"cashback",
"https://www.lomsnesvet.ca/wp-content/uploads/sites/21/2019/08/Kitten-Blog-683x1024.jpg"
),
BerubiExclusiveOfferResponse(
(body.page ?: 0) * 11 + 9,
"name",
"category",
1,
"cashback",
"https://www.lomsnesvet.ca/wp-content/uploads/sites/21/2019/08/Kitten-Blog-683x1024.jpg"
),
BerubiExclusiveOfferResponse(
(body.page ?: 0) * 11 + 10,
"name",
"category",
1,
"cashback",
"https://www.lomsnesvet.ca/wp-content/uploads/sites/21/2019/08/Kitten-Blog-683x1024.jpg"
)
)
)
)
传递给构造函数的第一个参数是 id。因此,在这种情况下,我希望收到无限列表,因为每个请求都会返回充满新元素的页面。然后我创建了DataSource
:
class BerubyMerchantsDataSource constructor(
private val requests: Requests,
private val requestBody: BerubyMerchantsByFilterRequest
) : RxPagingSource<Int, BerubiExclusiveOfferResponse>() {
override fun getRefreshKey(state: PagingState<Int, BerubiExclusiveOfferResponse>) =
state.anchorPosition?.let { anchorPosition ->
val anchorPage = state.closestPageToPosition(anchorPosition)
anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
}
override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, BerubiExclusiveOfferResponse>> {
val page = params.key ?: 1
requestBody.page = page
return requests.getBerubyMerchantsByFilter(requestBody)
.subscribeOn(Schedulers.io())
.map {
toLoadResult(it, page, 10)
}.onErrorReturn {
LoadResult.Error(it)
}
}
private fun toLoadResult(
response: BerubyMerchantsByFilterResponse,
currentPage: Int,
pageSize: Int
): LoadResult<Int, BerubiExclusiveOfferResponse> {
Timber.d("Loading page $currentPage")
val nextKey = if ((response.merchants?.size ?: 0) < pageSize) null else currentPage + 1
val prevKey = if (currentPage == 1) null else currentPage - 1
return LoadResult.Page(
response.merchants ?: listOf(),
prevKey,
nextKey
)
}
}
对于这种情况,我决定将页面大小设置为 10。在片段中,onResume
我添加了观察者:
CompositeDisposable().add(
controller.getMerchants().subscribe {
CoroutineScope(Dispatchers.Main).launch {
berubyMerchantsAdapter?.submitData(it)
}
}
)
到位于 Presenter 中的 Observable:
@ExperimentalCoroutinesApi
override fun getMerchants() = Pager(PagingConfig(10)) {
BerubyMerchantsDataSource(requests, requestModel)
}.observable
我还创建了适配器:
class BerubyMerchantsAdapter(diffCallback: DiffUtil.ItemCallback<BerubiExclusiveOfferResponse>) :
PagingDataAdapter<BerubiExclusiveOfferResponse, BerubyMerchantsAdapter.ViewHolder>(diffCallback) {
@SuppressLint("NonConstantResourceId")
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
@BindView(R.id.iv_merchant_logo)
internal lateinit var ivMerchantLogo: AppCompatImageView
@BindView(R.id.tv_merchant_name)
internal lateinit var tvMerchantName: AppCompatTextView
@BindView(R.id.tv_merchant_category)
internal lateinit var tvMerchantCategory: AppCompatTextView
@BindView(R.id.tv_merchant_cashback)
internal lateinit var tvMerchantCashback: AppCompatTextView
init {
ButterKnife.bind(this, itemView)
}
fun bindData(item: BerubiExclusiveOfferResponse) {
Glide.with(itemView.context).load(item.logoUrl).into(ivMerchantLogo)
tvMerchantName.text = item.name
tvMerchantCategory.text = item.category
tvMerchantCashback.text = item.cashback
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
getItem(position)?.let(holder::bindData)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.beruby_merchant_item, parent, false
)
)
}
并通过调用为其设置数据submitList()
但是当我运行应用程序时,我看到前两页立即加载,当我滚动到底部时,新页面没有加载。那么,这是怎么回事,我做错了什么?提前感谢您的帮助!