Android Paging分頁庫的學習(二)—— 結合Room數據庫進行分頁加載

Paging分頁庫的介紹

Paging分頁面是google推出的一個結合RecyclerView進行分頁加載數據的一個全新架構庫,主要是爲了解決一次性加載大量數據而形成的資源浪費問題。經過分頁的方式,每次加載一頁數據,既能夠加快界面的渲染,又能夠減小對象等資源的建立消耗。具體能夠看官網android

分頁庫主要由如下三個部分組成git

  • DataSource: 數據源,定義獲取數據的方式,有三種方式,分別是github

    1. PageKeyedDataSource
      2. ItemKeyedDataSource 
      3. PositionalDataSource.  基於位置信息進行數據的加載,和Room數據庫或者本地數據源一塊兒搭配。
    複製代碼
  • PagedListAdapter: 分頁庫適配器,繼承於RecyclerView的適配器,內部須要實現一個DiffUtil.ItemCallback差分器分析數據是否發生了改變。數據庫

  • PagedList: 定義分頁庫的配置,分別有默認加載數據大小,分頁數據大小等。而且經過PagedListAdapter將數據的變化進行更新。bash

1、經過Room數據庫進行分頁加載

(一)DataSource的生成

Room是google官方數據庫框架:Room,它是一個ORM框架。詳情能夠查看這裏。相對於本地數據源Android Paging分頁庫的學習(一)—— 結合本地數據進行分頁加載,使用Room生成DataSource.Factory 很簡單,只需在查詢的時候返回DataSource.Factory類型就能夠,以下圖 架構

這裏寫圖片描述
而Room在編譯期爲咱們生成具體的實現類的實現方法,以下
這裏寫圖片描述
而具體的邏輯實如今LimitOffsetDataSource裏面,咱們接着往下走,
這裏寫圖片描述
能夠看到LimitOffsetDataSource繼承於PositionalDataSource,而且能夠看到其中有兩個查詢語句是關鍵,分別是

  1. "SELECT COUNT(*) FROM ( " + mSourceQuery.getSql() + " )"; 獲取數據源的大小,這個很容易理解,就是獲得了所有要加載數據的總量。
  2. "SELECT * FROM ( " + mSourceQuery.getSql() + " ) LIMIT ? OFFSET ?"; 這是查詢數據表的方式,Limit是每次查詢的數量,對應着分頁的大小,Offset是查詢的偏移位置,對應着每一頁的起始位置。 因爲咱們是經過Room生成PositionalDataSource的,部分的原理就先講到這裏,具體的PositionalDataSource的使用留着在加載本地數據的時候再說明。詳情戳

(二)PagedListAdapter的實現

因爲PagedListAdapter繼承自RecyclerView的適配器,因此實現起來並不難,只是須要提供一個差分的實現用來進行數據的分析,代碼以下:框架

class ArticlePageAdapter : PagedListAdapter<ArticleEntity, ArticleViewHolder>(diffCallback) {
    override fun onBindViewHolder(holder: ArticleViewHolder, position: Int) {
        holder.bindTo(getItem(position))
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArticleViewHolder =
            ArticleViewHolder(parent)

    companion object {
        private val diffCallback = object : DiffUtil.ItemCallback<ArticleEntity>() {
            override fun areItemsTheSame(oldItem: ArticleEntity, newItem: ArticleEntity): Boolean =
                    oldItem.id == newItem.id

            override fun areContentsTheSame(oldItem: ArticleEntity, newItem: ArticleEntity): Boolean =
                    oldItem == newItem
        }
    }
}
複製代碼

(三)PagedList的配置

PagedList主要是設置分頁的大小,初始化加載的數據大小等配置。ide

val pagedListConfig =PagedList.Config.Builder().setEnablePlaceholders(true).setPageSize(10).setInitialLoadSizeHint(20).build()
 val pagedList = LivePagedListBuilder(articleDao.getAllByDataSource(), pagedListConfig).build()
複製代碼

經過以上代碼生成是一個帶LiveData的PagedListpost

(四)總結

配置好Room數據庫,生成DataSource負責數據來源, 接着實現PagedListAdapter負責UI的渲染,最後進行PagedList分頁的一些配置。生成一個帶LiveData的PagedList,一旦數據進行變化,便會通知pageAdapter調用submitList進行UI的更新學習

recycle_article.layoutManager = LinearLayoutManager(this)
   val pageAdapter = ArticlePageAdapter()
   recycle_article.adapter = pageAdapter 
   val articleDao = dataBase.articleDao()
   val pagedListConfig = PagedList.Config.Builder().setEnablePlaceholders(true).setPageSize(10).setInitialLoadSizeHint(20).build()
   val postList = LivePagedListBuilder(articleDao.getAllByDataSource(), pagedListConfig).build()
   postList.observe(this, Observer { pageAdapter.submitList(it)})

複製代碼

demo已經上傳,點擊傳送門,若有疑惑或者錯誤,歡迎指出。

相關文章
相關標籤/搜索