首页 > 解决方案 > 更新数据库记录时,分页列表(数据库 + 网络)触发 onItemAtEndLoaded

问题描述

我正在使用分页列表库构建一个 recyclerView。我从本地数据库中获取项目,当它到达最后一个时onItemAtEndLoaded()触发,然后调用 API 从网络中获取。

这些项目包含一个最喜欢的变量,因此当用户单击它时,我会更新数据库中的项目并刷新列表中的项目。

问题是,当我单击列表的最后一项并在数据库中更新它时,onItemAtEndLoaded()会触发该功能并从网络请求新项目。所以我不想被这个触发,因为没有什么可以获取的。

这是正常行为吗?我怎样才能避免它被调用?

干杯!

标签: androidandroid-recyclerviewandroid-roomandroid-architecture-componentspagedlist

解决方案


我现在为我的用例找到了解决方案/解决方法。它可能对其他具有类似 API 调用的人有所帮助,因此我将其发布在这里。

因为onItemAtEndLoaded()只要房间接触到桌子就会被调用(无论是通过 a@Query还是@UpdateDao 函数),我需要找到一种方法来阻止onItemAtEndLoaded()任何有意义的逻辑。

就我而言,我正在获取可下载文件 URL 的分页列表。当用户想要下载这样的文件时,我会在数据库中更新下载进度。因此,任何这些进度更新都会触发从 API 获取下一页。

因此,我告诉我的边界回调至少只获取到最后一个页码。我可以从 api 响应中获取此信息。所以这里有一些代码:

import retrofit2.Callback

abstract class NetworkBoundaryCallback<T> : Callback<T> {

    protected var nextPageNumber = 1
    private var maxPageNumber = Int.MAX_VALUE

    protected val ioExecutor: ExecutorService = Executors.newSingleThreadExecutor()
    private val helper = PagingRequestHelper(ioExecutor)

    fun onItemAtEndLoaded() {

        helper.runIfNotRunning(PagingRequestHelper.RequestType.AFTER) {
            pagingRequestCallback = it

            // check if next page number would exceed maxPageNumber
            if (nextPageNumber > maxPageNumber) {
                // if yes, return with failure message.
                val throwable = IllegalArgumentException("Maximum page number of $maxPageNumber already fetched")
                pagingRequestCallback.recordFailure(throwable)

            } else {
                // otherwise enqueue api call for next page
                createRequestCall().enqueue(this)

            }
        }
    }

    override fun onResponse(call: Call<T>, response: Response<T>) {
        ioExecutor.execute {
            val responseBody = response.body()
            if (responseBody !is PagedResponse<*>) return@execute

            // calculate maximum number of pages
            maxPageNumber = ceil(responseBody.totalItems / PAGE_SIZE).toInt()
            nextPageNumber = responseBody.page + 1
            doOnResponse(responseBody)
        }
    }

使用这个附加变量 ( maxPageNumber) 现在对我来说效果很好。

PagingRequestHelper 可以在这里找到


推荐阅读