Paging3 加載最后一頁,提示“沒有更多數(shù)據(jù)”功能

問題

使用 Paging3 處理分頁數(shù)據(jù),如果需要在 RecyclerView 底部增加【加載更多】的提示,可以通過調(diào)用 PagingDataAdapter 的 withLoadStateFooter() 方法,向其底部添加 LoadStateAdapter 的方式實現(xiàn)。

不過在開發(fā)中發(fā)現(xiàn),在 LoadStateAdapter 的 onBindViewHolder() 回調(diào)的 LoadState 狀態(tài),只有 LoadingError,卻沒有 NotLoading 狀態(tài),這樣不能實現(xiàn)【沒有更多數(shù)據(jù)】的狀態(tài)。

而且 LoadStateAdapter 中 item 展示的時機只有在 LoadingError 的狀態(tài)下,當加載最后一頁后,Paging3 不能給出任何提示,僅僅是不能滑動,這也太挫了吧!

分析

猜測 LoadStateAdapter 中應(yīng)該有可以控制 item 顯示和隱藏的方法,LoadStateAdapter 的源碼不多,果然在最后發(fā)現(xiàn)了一個可以重寫的方法:

/**
 * Returns true if the LoadState should be displayed as a list item when active.
 *
 * By default, [LoadState.Loading] and [LoadState.Error] present as list items, others do not.
 */
open fun displayLoadStateAsItem(loadState: LoadState): Boolean {
    return loadState is LoadState.Loading || loadState is LoadState.Error
}

注釋說的很清楚了,默認情況下,LoadState.LoadingLoadState.Error 顯示 item,其他狀態(tài)則不顯示。

那我們再來看看,它是用如何利用 displayLoadStateAsItem() 控制 item 的顯示與隱藏:

/**
 * LoadState to present in the adapter.
 *
 * Changing this property will immediately notify the Adapter to change the item it's
 * presenting.
 */
var loadState: LoadState = LoadState.NotLoading(endOfPaginationReached = false)
    set(loadState) {
        if (field != loadState) {
            val oldItem = displayLoadStateAsItem(field)
            val newItem = displayLoadStateAsItem(loadState)

            if (oldItem && !newItem) {//舊狀態(tài)為Loading或Error,新狀態(tài)為NotLoading
                notifyItemRemoved(0)//隱藏
            } else if (newItem && !oldItem) {//舊狀態(tài)為NotLoading,新狀態(tài)為Loading或Error
                notifyItemInserted(0)// 顯示
            } else if (oldItem && newItem) {//舊狀態(tài)為Loading或Error,新狀態(tài)為Loading或Error
                notifyItemChanged(0)// 顯示(刷新)
            }
            field = loadState
        }
    }

item 的顯示規(guī)則,我已經(jīng)注釋的很清楚了,總結(jié)一句話:如果想要展示 item,就需要 newItem 的返回值為 true。

解決方案

我們的目標是,在【沒有更多數(shù)據(jù)】時,顯示 item,此時 LoadState 的狀態(tài)是 NotLoading,并且 NotLoading 中有個 endOfPaginationReached 變量,我們看下對它的描述:

endOfPaginationReached - false if there is more data to load in the LoadType this LoadState is associated with, true otherwise. This parameter informs Pager if it should continue to make requests for additional data in this direction or if it should halt as the end of the dataset has been reached.

可以看到當 endOfPaginationReached 為 true 時,表示沒有更多數(shù)據(jù)了。

所以我們只要重寫 displayLoadStateAsItem() 方法,就可以實現(xiàn),【沒有更多數(shù)據(jù)】的提示了:

override fun displayLoadStateAsItem(loadState: LoadState): Boolean {
    return super.displayLoadStateAsItem(loadState)
            || (loadState is LoadState.NotLoading && loadState.endOfPaginationReached)
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容