溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Paging庫怎么在Android 中使用

發(fā)布時(shí)間:2021-03-26 17:12:27 來源:億速云 閱讀:173 作者:Leah 欄目:移動(dòng)開發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)Paging庫怎么在Android 中使用,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

添加分頁依賴

按照如下代碼添加依賴:

dependencies {
  def paging_version = "1.0.0"

  implementation "android.arch.paging:runtime:$paging_version"

  // alternatively - without Android dependencies for testing
  testImplementation "android.arch.paging:common:$paging_version"

  // optional - RxJava support, currently in release candidate
  implementation "android.arch.paging:rxjava2:1.0.0-rc1"
}

備注: 分頁包幫助開發(fā)者在UI的列表容器中順暢地展示數(shù)據(jù), 而不管是使用設(shè)備內(nèi)部的數(shù)據(jù)庫還是從應(yīng)用后端拉取數(shù)據(jù).

庫架構(gòu)

分頁庫的核心構(gòu)件是PagedList類, 它是一個(gè)集合, 用于異步加載應(yīng)用數(shù)據(jù)塊或者數(shù)據(jù)頁. 該類在應(yīng)用的其它架構(gòu)之間充當(dāng)中介.

Data

每一個(gè)PagedList實(shí)例從DataSource中加載最新的應(yīng)用數(shù)據(jù). 數(shù)據(jù)從應(yīng)用后端或者數(shù)據(jù)庫流入PagedList對象. 分頁包支持多樣的應(yīng)用架構(gòu), 包括脫機(jī)數(shù)據(jù)庫和與后臺服務(wù)器通訊的數(shù)據(jù)庫.

UI

PagedList類通過PagedListAdapter加載數(shù)據(jù)項(xiàng)到RecyclerView里面. 在加載數(shù)據(jù)的時(shí)候, 這些類協(xié)同工作, 拉取數(shù)據(jù)并展示內(nèi)容, 包括預(yù)取看不見的內(nèi)容并在內(nèi)容改變時(shí)加載動(dòng)畫.

支持不同的數(shù)據(jù)架構(gòu)

分頁包支持應(yīng)用架構(gòu), 包括應(yīng)用拉取數(shù)據(jù)的地方是從后臺服務(wù)器, 還是本機(jī)數(shù)據(jù)庫, 還是兩者的結(jié)合.

只有網(wǎng)絡(luò)

要展示后臺數(shù)據(jù), 需要使用Retrofit的同步版本, 加載信息到自定義的DataSource對象中.
備注: 分頁包的DataSource對象并沒有提供任何錯(cuò)誤處理機(jī)制, 因?yàn)椴煌膽?yīng)用需要用不同的方式處理和展示UI錯(cuò)誤. 如果錯(cuò)誤發(fā)生了, 順從結(jié)果的回調(diào), 然后稍后重試.

只有數(shù)據(jù)庫

要設(shè)置RecyclerView觀測本地存儲, 偏向于使用Room持久化庫. 用這種方式, 無論任何時(shí)候數(shù)據(jù)庫數(shù)據(jù)插入或者修改, 這些改變會自動(dòng)地在負(fù)責(zé)展示這些數(shù)據(jù)的RecyclerView展示出來.

網(wǎng)絡(luò)+數(shù)據(jù)庫

在開始觀測數(shù)據(jù)庫之后, 你能夠通過使用PagedList.BoundaryCallback來監(jiān)聽數(shù)據(jù)庫什么時(shí)候過期. 之后, 你可能從網(wǎng)絡(luò)拉取更多的數(shù)據(jù), 并把它們插入到數(shù)據(jù)庫中. 如果UI正在展示數(shù)據(jù)庫, 以上就是你所需要做的全部.

下面的代碼片斷展示了BoundaryCallback的使用實(shí)例:

class ConcertViewModel {
  fun search(query: String): ConcertSearchResult {
    val boundaryCallback =
        ConcertBoundaryCallback(query, myService, myCache)
    // Error-handling not shown in this snippet.
    val networkErrors = boundaryCallback.networkErrors
  }
}

class ConcertBoundaryCallback(
    private val query: String,
    private val service: MyService,
    private val cache: MyLocalCache
) : PagedList.BoundaryCallback<Concert>() {
  override fun onZeroItemsLoaded() {
    requestAndSaveData(query)
  }

  override fun onItemAtEndLoaded(itemAtEnd: Concert) {
    requestAndSaveData(query)
  }
}

處理網(wǎng)絡(luò)錯(cuò)誤

在使用網(wǎng)絡(luò)拉取或者分頁的數(shù)據(jù), 而這些數(shù)據(jù)正在使用分頁包展示的時(shí)候, 不總是把網(wǎng)絡(luò)分為要么"可用"要么"不可能"是很重要的, 因?yàn)樵S多連接是間歇性或者成片的:

  • 特定的服務(wù)器可能不能響應(yīng)網(wǎng)絡(luò)請求;

  • 設(shè)備可能聯(lián)接了慢的或者弱的網(wǎng)絡(luò);

應(yīng)用應(yīng)該檢查每一個(gè)請求是否成功, 并且在網(wǎng)絡(luò)不可用的情形下, 盡可能快地恢復(fù). 比如, 你可以為用戶提供一個(gè)"重試"按鈕, 如果數(shù)據(jù)沒有刷新成功的話. 如果在數(shù)據(jù)分頁期間發(fā)生錯(cuò)誤, 最好自動(dòng)地重新分頁請求.

更新已有應(yīng)用

如果應(yīng)用已經(jīng)從網(wǎng)絡(luò)或者數(shù)據(jù)庫消費(fèi)數(shù)據(jù), 很大可能可以直接升級到分頁庫提供的功能.

自定義分頁解決方案

如果你使用了自定義功能加載數(shù)據(jù)源中的小的數(shù)據(jù)集, 你可以使用PagedList類取代這個(gè)邏輯. PagedList類實(shí)例提供了內(nèi)建的連接, 到通用的數(shù)據(jù)源. 這些實(shí)例也提供了在應(yīng)用中引用的RecyclerView的適配器.

使用列表而非分頁加載的數(shù)據(jù)

如果你使用內(nèi)存里的列表作為UI適配器的后備數(shù)據(jù)結(jié)構(gòu), 考慮使用PagedList類觀測數(shù)據(jù)更新, 如果列表中數(shù)據(jù)項(xiàng)變得很多的話. PagedList實(shí)例既可以使用LiveData<PagedList>也可以使用Observable<List>對UI傳遞數(shù)據(jù)更新, 同時(shí)最小化了加載時(shí)間和內(nèi)存使用. 然而, 應(yīng)用中使用PagedList對象代替List并不要求對UI結(jié)構(gòu)和數(shù)據(jù)更新邏輯作任何改變.

使用CursorAdapter將數(shù)據(jù)cursor與列表視圖聯(lián)系起來

應(yīng)用也許會使用CursorAdapter將數(shù)據(jù)從Cursor跟ListView連接起來. 在這種情況下, 通常需要從ListView遷移到RecyclerView, 然后使用Room或者PositionalDataSource構(gòu)件代替Cursor, 當(dāng)然, 這主要依據(jù)于Cursor實(shí)例能否訪問SQLite數(shù)據(jù)庫.

在一些情況下, 比如使用Spinner實(shí)例的時(shí)候, 你僅僅提供了Adapter本身. 然后一個(gè)庫使用了加載進(jìn)adapter中的數(shù)據(jù), 并展示了數(shù)據(jù). 在這些情況下, 把a(bǔ)dapter數(shù)據(jù)類型轉(zhuǎn)化為LiveData<PagedList>, 之后在嘗試使用將這些數(shù)據(jù)項(xiàng)在UI中填充起來之前, 將這個(gè)列表在ArrayAdapter對象中包裹起來.

使用AsyncListUtil異步加載內(nèi)容

如果你在使用AsyncListUtil對象異步地加載和展示分組信息的話, 分頁包將會使得加載數(shù)據(jù)更加方便:

  • 數(shù)據(jù)并不需要定位. 分頁包讓你直接從后臺使用網(wǎng)絡(luò)提供的鍵加載數(shù)據(jù).

  • 數(shù)據(jù)量太大. 使用分頁包可以將數(shù)據(jù)加載分頁直到?jīng)]有任何數(shù)據(jù)留下.

  • 更方便地觀測數(shù)據(jù). 分頁包能夠展示應(yīng)用在可觀測數(shù)據(jù)結(jié)構(gòu)中持有的ViewModel.

 數(shù)據(jù)庫例子

 使用LiveData觀測分頁數(shù)據(jù)

下面的示例代碼展示了所有一起工作的碎片. 當(dāng)演唱會事件在數(shù)據(jù)庫中添加, 刪除或者修改的修改的時(shí)候, RecyclerView中的內(nèi)容自動(dòng)且高效地更新:

@Dao
interface ConcertDao {
  // The Integer type parameter tells Room to use a PositionalDataSource
  // object, with position-based loading under the hood.
  @Query("SELECT * FROM user ORDER BY concert DESC")
  fun concertsByDate(): DataSource.Factory<Int, Concert>
}

class MyViewModel(concertDao: ConcertDao) : ViewModel() {
  val concertList: LiveData<PagedList<Concert>> = LivePagedListBuilder(
      concertDao.concertsByDate(),
      /* page size */ 20
  ).build()
}

class MyActivity : AppCompatActivity() {
  public override fun onCreate(savedState: Bundle?) {
    super.onCreate(savedState)
    val viewModel = ViewModelProviders.of(this)
        .get(MyViewModel::class.java!!)
    val recyclerView = findViewById(R.id.concert_list)
    val adapter = ConcertAdapter()
    viewModel.concertList.observe(this, { pagedList ->
        adapter.submitList(pagedList) })
    recyclerView.setAdapter(adapter)
  }
}

class ConcertAdapter() :
    PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) {
  fun onBindViewHolder(holder: ConcertViewHolder, position: Int) {
    val concert = getItem(position)
    if (concert != null) {
      holder.bindTo(concert)
    } else {
      // Null defines a placeholder item - PagedListAdapter automatically
      // invalidates this row when the actual object is loaded from the
      // database.
      holder.clear()
    }
  }

  companion object {
    private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Concert>() {
      // Concert details may have changed if reloaded from the database,
      // but ID is fixed.
      override fun areItemsTheSame(oldConcert: Concert,
          newConcert: Concert): Boolean =
          oldConcert.id == newConcert.id

      override fun areContentsTheSame(oldConcert: Concert,
          newConcert: Concert): Boolean =
          oldConcert == newConcert
    }
  }
}

使用RxJava2觀測分頁數(shù)據(jù)

如果你偏愛使用RxJava2而非LiveData, 那么你可以創(chuàng)建Observable或者Flowable對象:

 class MyViewModel(concertDao: ConcertDao) : ViewModel() {
   val concertList: Flowable<PagedList<Concert>> = RxPagedListBuilder(
       concertDao.concertsByDate(),
       /* page size */ 50
   ).buildFlowable(BackpressureStrategy.LATEST)
 }

之后你可以按照如下代碼開始和停止觀測數(shù)據(jù):

class MyActivity : AppCompatActivity() {
  private lateinit var adapter: ConcertAdapter<Concert>
  private lateinit var viewModel: MyViewModel

  private val disposable = CompositeDisposable()

  public override fun onCreate(savedState: Bundle?) {
    super.onCreate(savedState)
    val recyclerView = findViewById(R.id.concert_list)
    viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java!!)
    adapter = ConcertAdapter()
    recyclerView.setAdapter(adapter)
  }

  override fun onStart() {
    super.onStart()
    disposable.add(viewModel.concertList.subscribe({
        flowableList -> adapter.submitList(flowableList)
    }))
  }

  override fun onStop() {
    super.onStop()
    disposable.clear()
  }
}

基于RxJava2解決方案的ConcertDao和ConcertAdapter代碼, 和基于LiveData解決方案的代碼是一樣的.

UI構(gòu)件及其出發(fā)點(diǎn)

將UI和視圖模型聯(lián)接起來 

你可以按照如下方式, 將LiveData<PagedList>實(shí)例跟PagedListAdapter聯(lián)系起來:

private val adapter = ConcertPagedListAdapter()
private lateinit var viewModel: ConcertViewModel

override fun onCreate(savedInstanceState: Bundle?) {
  viewModel = ViewModelProviders.of(this)
      .get(ConcertViewModel::class.java)
  viewModel.concerts.observe(this, adapter::submitList)
}

當(dāng)數(shù)據(jù)源提供一個(gè)新PagedList實(shí)例的時(shí)候, activity會將這些對象改善給adapter. PagedListAdapter實(shí)現(xiàn), 定義了更新如何計(jì)算, 自動(dòng)地處理分頁和列表不同. 由此, 你的ViewHolder只需要綁定到特定的提供項(xiàng):

class ConcertPagedListAdapter() : PagedListAdapter<Concert, ConcertViewHolder>(
    object : DiffUtil.ItemCallback<Concert>() {
  // The ID property identifies when items are the same.
  override fun areItemsTheSame(oldItem: Concert, newItem: Concert)
      = oldItem.id = newItem.id

  // Use the "==" operator (or Object.equals() in Java-based code) to know
  // when an item's content changes. Implement equals(), or write custom
  // data comparison logic here.
  override fun areContentsTheSame(oldItem: Concert, newItem: Concert) =
      oldItem.name == newItem.name && oldItem.date == newItem.date
  }
) {
  override fun onBindViewHolder(holder: ConcertViewHolder, position: Int) {
    val concert: Concert? = getItem(position)

    // Note that "concert" is a placeholder if it's null
    holder.bind(concert)
  }
}

PagedListAdapter使用PagedList.Callback對象處理分頁加載事件. 當(dāng)用戶滑動(dòng)時(shí), PagedListAdapter調(diào)用PagedList.loadAround()方法將從DataSource中拉聚攏數(shù)據(jù)項(xiàng)提示提供給基本的PagedList.
備注: PageList是內(nèi)容不可變的. 這意味著, 盡管新內(nèi)容能夠被加載到PagedList實(shí)例中, 但已加載項(xiàng)一旦加載完成便不能發(fā)生改變. 由此, 如果PagedList中的內(nèi)容發(fā)生改變, PagedListAdapter對象將會接收到一個(gè)包含已更新信息的全新的PagedList.

實(shí)現(xiàn)diffing回調(diào)

先前的代碼展示了areContentsTheSame()的手動(dòng)實(shí)現(xiàn), 它比較了對象的相關(guān)的域. 你也可以使用Java中的Object.equals()方法或者Kotlin中的==操作符. 但是要確保要么實(shí)現(xiàn)了對象中的equals()方法或者使用了kotlin中的數(shù)據(jù)對象.

使用不同的adapter類型進(jìn)行diffing

如果你選擇不從PagedListAdapter繼承--比如你在使用一個(gè)提供了自己的adapter的庫的時(shí)候--你依然可以通過直接使用AsyncPagedListDiffer對象使用分頁包adapter的diffing功能.

在UI中提供占位符

在應(yīng)用完成拉取數(shù)據(jù)之前, 如果你想U(xiǎn)I展示一個(gè)列表, 你可以向用戶展示占位符列表項(xiàng). RecyclerView通過將列表項(xiàng)臨時(shí)地設(shè)置為null來處理這個(gè)情況.

備注: 默認(rèn)情況下, 分頁包開啟了占位符行為.

占位符有如下好處:

  • 支持scrollbar. PagedList向PagedListAdapter提供了大量的列表項(xiàng). 這個(gè)信息允許adapter繪制一個(gè)表示列表已滿的scrollbar. 當(dāng)新的頁加載時(shí), scrollbar并不會跳動(dòng), 因?yàn)榱斜硎遣⒉粵]有改變它的size.

  • 不需要"正在加載"旋轉(zhuǎn)指針. 因?yàn)榱斜泶笮∫阎? 沒必要提醒用戶有更多的數(shù)據(jù)項(xiàng)正在加載. 占位符本身表達(dá)了這個(gè)信息.

在添加占位符的支持之前, 請牢記以下先置條件:

  • 要求集合中數(shù)據(jù)可數(shù). 來自Room持久化庫的DataSource實(shí)例能夠高效地計(jì)算數(shù)據(jù)項(xiàng). 然而, 如果你在用自定義本地存儲方案或者只有網(wǎng)絡(luò)的數(shù)據(jù)架構(gòu), 想了解數(shù)據(jù)集中有多少數(shù)據(jù)項(xiàng)可能代價(jià)很高, 甚至不可能.

  • 要求adapter負(fù)責(zé)未加載數(shù)據(jù)項(xiàng). 你正在使用的adapter或者展示機(jī)制來準(zhǔn)備填充列表, 需要處理null列表項(xiàng). 比如, 當(dāng)將數(shù)據(jù)綁定到ViewHolder的時(shí)候, 你需要提供默認(rèn)值表示未加載數(shù)據(jù).

  • 要求數(shù)據(jù)相同數(shù)量的item view. 如果列表項(xiàng)數(shù)目能夠基于內(nèi)容發(fā)生改變, 比如, 社交網(wǎng)絡(luò)更新, 交叉淡入淡出看起來并不好. 在這種情況下, 強(qiáng)烈推薦禁掉占位符.

數(shù)據(jù)構(gòu)件及其出發(fā)點(diǎn)

構(gòu)建可觀測列表

通常情況下, UI代碼觀測LiveData<PagedList>對象(或者, 如果你在使用RxJava2, 是Flowable<PagedList>/Observable<PagedList>對象), 這個(gè)對象存在于應(yīng)用的ViewModel中. 這個(gè)可觀測對象形成了應(yīng)用列表數(shù)據(jù)內(nèi)容和展示的連接.

要?jiǎng)?chuàng)建這么一個(gè)可觀測PagedList對象, 需要將DataSource.Factory實(shí)例傳給LivePageListBuilder/RxPagedListBuilder對象. 一個(gè)DataSource對象對單個(gè)PagedList加載分頁. 這個(gè)工廠類為內(nèi)容更新創(chuàng)建PagedList實(shí)例, 比如數(shù)據(jù)庫表驗(yàn)證, 網(wǎng)絡(luò)刷新等. Room持久化庫能夠提供DataSource.Factory, 或者自定義.

如下代碼展示了如何在應(yīng)用的ViewModel類中使用Room的DataSource.Factory構(gòu)建能力創(chuàng)建新的LiveData<PagedaList>實(shí)例:

ConcertDao.kt:

interface ConcertDao {
   // The Integer type parameter tells Room to use a PositionalDataSource
   // object, with position-based loading under the hood.
   @Query("SELECT * FROM concerts ORDER BY date DESC")
   public abstract DataSource.Factory<Integer, Concert> concertsByDate()
 }

ConcertViewModel.kt:

// The Integer type argument corresponds to a PositionalDataSource object.
val myConcertDataSource : DataSource.Factory<Integer, Concert> =
    concertDao.concertsByDate()

val myPagedList = LivePagedListBuilder(myConcertDataSource, /* page size */ 20)
    .build()

定義分頁配置

要想為復(fù)雜情形更深入地配置LiveData<PagedList>, 你也可以定義自己的分頁配置. 尤其是, 你可以定義如下屬性:

  • 頁大小: 每一頁的數(shù)據(jù)量.

  • 預(yù)取距離: 給定UI中最后可見項(xiàng), 超過該項(xiàng)之后多少項(xiàng), 分頁包要嘗試提前提取數(shù)據(jù). 這個(gè)值應(yīng)該比page size大幾倍.

  • 占位符展示: 決定了UI是否會為還沒有完成加載的數(shù)據(jù)項(xiàng)展示占位符.

如果你想要對分布包從數(shù)據(jù)庫加載中設(shè)置更多的控件, 要像下面的代碼一樣, 傳遞自定義的Executor對象給LivePagedListBuilder:

EventViewModel.kt:

val myPagingConfig = PagedList.Config.Builder()
    .setPageSize(50)
    .setPrefetchDistance(150)
    .setEnablePlaceholders(true)
    .build()

// The Integer type argument corresponds to a PositionalDataSource object.
val myConcertDataSource : DataSource.Factory<Integer, Concert> =
    concertDao.concertsByDate()

val myPagedList = LivePagedListBuilder(myConcertDataSource, myPagingConfig)
    .setFetchExecutor(myExecutor)
    .build()

選擇正確的數(shù)據(jù)源類型

連接更最好地處理源數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)源很重要:

  • 如果加載的頁嵌套了之前/之后頁的key的話, 使用PageKeyDataSource. 比如, 比如你正在從網(wǎng)絡(luò)中拉取社交媒體博客, 你也許需要傳遞從一次加載向下一次加載的nextPage token.

  • 如果需要使用每N項(xiàng)數(shù)據(jù)項(xiàng)的數(shù)據(jù)拉取每N+1項(xiàng)的話, 使用ItemKeyedDataSource. 比如, 你在為一個(gè)討論型應(yīng)用拉取螺紋評論, 你可能需要傳遞最后一條評論的ID來獲取下一條評論的內(nèi)容.

  • 如果你需要從數(shù)據(jù)商店中的任意位置拉取分頁數(shù)據(jù)的話, 使用PositionalDataSource. 這個(gè)類支持請求任意位置開始的數(shù)據(jù)集. 比如, 請求也許返回從位置1200開始的20條數(shù)據(jù).

通知數(shù)據(jù)非法

在使用分頁包時(shí), 在表或者行數(shù)據(jù)變得陳腐時(shí), 取決于數(shù)據(jù)層來通知應(yīng)用的其它層. 要想這么做的話, 需要從DataSource類中調(diào)用invalidate()方法.

備注: UI也可以使用"滑動(dòng)刷新"模式來觸發(fā)數(shù)據(jù)非法功能.

構(gòu)建自己的數(shù)據(jù)源

如果你使用了自定義的數(shù)據(jù)解決方案, 或者直接從網(wǎng)絡(luò)加載數(shù)據(jù), 你可以實(shí)現(xiàn)一個(gè)DataSource子類. 下面的代碼展示了數(shù)據(jù)源從給定的concert起始時(shí)間切斷:

class ConcertTimeDataSource(private val concertStartTime: Date) :
    ItemKeyedDataSource<Date, Concert>() {
  override fun getKey(item: Concert) = item.startTime

  override fun loadInitial(
      params: LoadInitialParams<Date>,
      callback: LoadInitialCallback<Concert>) {
    val items = fetchItems(concertStartTime, params.requestedLoadSize)
    callback.onResult(items)
  }

  override fun loadAfter(
      params: LoadParams<Date>,
      callback: LoadCallback<Concert>) {
    val items = fetchItemsAfter(
      date = params.key,
      limit = params.requestedLoadSize)
    callback.onResult(items)
  }
}

通過創(chuàng)建真實(shí)的DataSource.Factory子類, 你之后能夠加載自定義的數(shù)據(jù)到PagedList對象. 下面的代碼展示了如何創(chuàng)建在之前代碼中定義的自定義數(shù)據(jù)源:

class ConcertTimeDataSourceFactory(private val concertStartTime: Date) :
    DataSource.Factory<Date, Concert>() {
  val sourceLiveData = MutableLiveData<ConcertTimeDataSource>()
  override fun create(): DataSource<Date, Concert> {
    val source = ConcertTimeDataSource(concertStartTime)
    sourceLiveData.postValue(source)
    return source
  }
}

考慮內(nèi)容更新

當(dāng)你構(gòu)建可觀測PagedList對象的時(shí)候, 考慮一下內(nèi)容是如何更新的. 如果你直接從Room數(shù)據(jù)庫中加載數(shù)據(jù), 更新會自動(dòng)地推送到UI上面.

如果你在使用分頁的網(wǎng)絡(luò)API, 通常你會有用戶交互, 比如"滑動(dòng)刷新", 把它作為信號去驗(yàn)證當(dāng)前DataSource非法并請求一個(gè)新的. 這個(gè)行為出行在下面的代碼中:

class ConcertActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    ...

    concertViewModel.refreshState.observe(this, Observer {
      swipeRefreshLayout.isRefreshing =
          it == NetworkState.LOADING
    })
    swipeRefreshLayout.setOnRefreshListener {
      concertViewModel.invalidateDataSource()
    }
  }
}

提供數(shù)據(jù)表現(xiàn)之間的映射

對于DataSource加載的數(shù)據(jù), 分頁包支持基于數(shù)據(jù)項(xiàng)和基于頁的轉(zhuǎn)換.

下面的代碼中, concert名和日期的聯(lián)合被映射成包含姓名和日期的字符串:

class ConcertViewModel : ViewModel() {
  val concertDescriptions : LiveData<PagedList<String>>
    init {
      val factory = database.allConcertsFactory()
          .map { concert ->
              concert.name + " - " + concert.date
          }
      concerts = LivePagedListBuilder(factory, 30).build()
    }
  }
}

如果在數(shù)據(jù)加載之后, 想要包裹, 轉(zhuǎn)換或者準(zhǔn)備item, 這將非常有用. 因?yàn)檫@個(gè)工作是在獲取執(zhí)行器中完成的, 你可以在其中執(zhí)行花銷巨大的工作, 比如, 從硬盤中讀取, 查詢數(shù)據(jù)庫等.

關(guān)于Paging庫怎么在Android 中使用就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI