1

我尝试使用 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()

但是当我运行应用程序时,我看到前两页立即加载,当我滚动到底部时,新页面没有加载。那么,这是怎么回事,我做错了什么?提前感谢您的帮助!

4

0 回答 0