iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 19
0

Paging (一) 概念

Android 應用程式中要呈現列表(List)資料,都會使用 RecyclerView 這個元件,雖然 RecyclerView 已經非常方便,將大部分處理列表資料的邏輯都寫好了,但是要處理 分頁 這個功能時還是相當麻煩,於是 Google 在 2018 年推出了 Paging 這個組件專門來處理分頁這個邏輯。

什麼是分頁,為什麼需要分頁

在 RecyclerView 要呈現資料,會先把資料拿到後丟給 adapter,再呼叫 notifyDataSetChanged 更新 UI

class HomeAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>(){

    private var articleList: List<Article> = listOf()
    .
    .
    .
    
    fun onBindArticleList(articleList: List<Article>) {
    
        this.articleList = articleList
        notifyDataSetChanged()
    }
}

那如果這個 List 的資料量非常龐大,成千上萬筆,那一開始就會等全部的資料拿到了才會顯示出來,可能會等非常久,造成使用者體驗不好,所以如果可以先載入一個頁面要顯示的資料,等到往下滑快要沒有資料時再去拿後面的資料,處理的速度就會快很多,使用者體驗也會大幅提升。

所以就衍生出了某些 API 會把一大筆資料分成好幾份,並在拿資料時帶入 page 之類的參數來取得你想要的是第幾頁的資料。

https://free-nba.p.rapidapi.com/players?page=2
//取得第二頁的資料

在 RecyclerView 裡面就需要設定 addOnScrollListener 去監聽 RecyclerView 的滑動事件,在滑到底時計算 page,再丟給 API 取得資料。

Paging 有哪些優點

  1. 將資料讀取的初始化、資料讀取前、資料讀取後的方法都封裝好了,開發者可以直接調用這些方法不需要自己寫。

  2. 可以監聽 RecyclerView 裡的項目數量,滑到最後一筆的資料時、滑到沒有資料時、資料讀取錯誤的處理, 再也不用在 RecyclerView 裡面自己寫監聽事件。

  3. 提供與 Room 數據庫的整合

  4. 使用 DiffUtil 這個類別來定義每個 Item 替換的時機,提升效能。

  5. 能夠自己設定一次要載入的 Item 數量、在滑到最後一筆之前就預先載入下一頁的資料,會讓使用者有無限列表的感覺。
    白話一點就是滑起來會非常流暢,不會有滑到底時還要再去轉圈圈要資料的卡頓感。

Paging 由三大部分所組成 DataSourcePagedListPagedAdapter

DataSource

定義 Datasource<Key, Value> 來包裝數據類,其中 Key 對應加載數據的唯一識別碼, Value 對應返回結果,針對不同場景,Paging提供了三種數據源

PageKeyedDataSource <Key,Value>:適用於目標數據根據頁信息請求數據的場景,即 Key 字段是下一頁相關的信息。比如請求的數據的參數中包含類似 nextPage、previousPage 之類的信息。

ItemKeyedDataSource <Key,Value>:適用於目標數據的加載依賴特定項目的信息,即 Key 字段包含的是項目中的信息,比如需要根據第 N 項的信息加載第 N + 1 項的數據,傳參中需要傳入第 n 項的 ID 時,該場景多出現於論壇類應用評論信息的請求。

PositionalDataSource :適用於目標數據總數固定,通過特定的位置加載數據,這裡 Key 是表示想要載入的位置,T 即值。比例從數據庫中的 1500 條開始載入 50 條數據。

PagedList

作為 DataSourcePagedAdapter的轉接頭,是 List 的子類,支持所有 List 的操作,在裡面可以去做資料載入的設定和邏輯處理。

  • MainThreadExecutor 用來將結果丟回主線程的 Excutor

  • BackgroundThreadExecutor 背景的 Excutor

  • BoundaryCallbackDataSource 要資料時的回調

  • ConfigDataSource 取資料的設定,其中:

    pageSize:設置每頁加載的數量
    prefetchDistance:預加載的數量
    initialLoadSizeHint:初始化數據時加載的數量
    enablePlaceholders:當項目為空是否需要 Placeholder 默認為 true

PagedListAdapter

用來替換掉 RecyclerView.Adapter 的類別,用來監聽 PagedList 的變化,且必須實作 DiffCallback 來完成替換數據的邏輯。

概念大概是這些,細節後面會慢慢補充,明天進入實作的部分!

有任何問題或講得不清楚的地方歡迎留言和我討論。

更歡迎留言糾正我任何說錯的地方!

下一篇:Paging (二) NetWork Datasource


上一篇
Day 18 Room (Last) 其他應用與總結
下一篇
Day 20 Paging (二) NetWork Datasource
系列文
Android Architecture Components 學習心得筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言