顯示分頁清單

本指南以「分頁庫總覽」為基礎,說明如何在應用程式 UI 中向使用者顯示資訊清單 (尤其是在這些資訊變更時)。

將使用者介面連結至資料檢視模型

您可以將 LiveData<PagedList> 的例項連線至 PagedListAdapter,如以下程式碼片段所示:

Kotlin

class ConcertActivity : AppCompatActivity() {
    private val adapter = ConcertAdapter()

    // Use the 'by viewModels()' Kotlin property delegate
    // from the activity-ktx artifact
    private val viewModel: ConcertViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState);
        viewModel.concerts.observe(this, Observer { adapter.submitList(it) })
    }
}

Java

public class ConcertActivity extends AppCompatActivity {
    private ConcertAdapter adapter = new ConcertAdapter();
    private ConcertViewModel viewModel;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        viewModel = new ViewModelProvider(this).get(ConcertViewModel.class);
        viewModel.concertList.observe(this, adapter::submitList);
    }
}

資料來源提供 PagedList 的新例項時,活動會將這些物件傳送至轉接程式。PagedListAdapter 實作定義了更新如何計算,且會自動處理分頁和清單差異。因此,您的 ViewHolder 只需要繫結至特定提供的項目:

Kotlin

class ConcertAdapter() :
        PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) {
    override fun onBindViewHolder(holder: ConcertViewHolder, position: Int) {
        val concert: Concert? = getItem(position)

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

    companion object {
        private val DIFF_CALLBACK = ... // See Implement the diffing callback section.
    }
}

Java

public class ConcertAdapter
        extends PagedListAdapter<Concert, ConcertViewHolder> {
    protected ConcertAdapter() {
        super(DIFF_CALLBACK);
    }

    @Override
    public void onBindViewHolder(@NonNull ConcertViewHolder holder,
            int position) {
        Concert concert = getItem(position);

        // Note that "concert" can be null if it's a placeholder.
        holder.bindTo(concert);
    }

    private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK
            = ... // See Implement the diffing callback section.
}

PagedListAdapter 會使用 PagedList.Callback 物件處理頁面載入事件。使用者捲動畫面時,PagedListAdapter 會呼叫 PagedList.loadAround(),向 PagedList 提供提示,為從 DataSource 擷取項目。

實作差異化回呼

以下範例顯示 areContentsTheSame() 的手動實作,比較相關物件欄位:

Kotlin

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

    // If you use the "==" operator, make sure that the object implements
    // .equals(). Alternatively, write custom data comparison logic here.
    override fun areContentsTheSame(
            oldItem: Concert, newItem: Concert) = oldItem == newItem
}

Java

private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK =
        new DiffUtil.ItemCallback<Concert>() {

    @Override
    public boolean areItemsTheSame(Concert oldItem, Concert newItem) {
        // The ID property identifies when items are the same.
        return oldItem.getId() == newItem.getId();
    }

    @Override
    public boolean areContentsTheSame(Concert oldItem, Concert newItem) {
        // Don't use the "==" operator here. Either implement and use .equals(),
        // or write custom data comparison logic here.
        return oldItem.equals(newItem);
    }
};

由於轉接程式包含了比較項目的定義,所以載入新的 PagedList 物件時,轉接程式會自動偵測這些項目的變更。因此,轉接程式會觸發 RecyclerView 物件中有效的項目動畫。

比較使用其他不同轉接程式類型差異

如果您選擇不沿用 PagedListAdapter,例如當您使用的程式庫已提供自己的轉接程式,您還是可以透過 AsyncPagedListDiffer 物件來直接使用「分頁庫」轉接程式差異比較的功能。

在 UI 中提供預留位置

如果希望 UI 在應用程式擷取資料前顯示清單,來向使用者顯示預留位置清單項目。PagedList 會將清單項目資料顯示為 null,直到資料載入完成,才處理這種情況。

預留位置具備下列優點:

  • 支援捲軸:PagedList 提供清單項目數量給 PagedListAdapter。這項資訊可讓轉接程式繪製用來傳送清單完整大小的捲軸。當新頁面載入時,捲軸不會跳轉,因為您的清單不會改變大小。
  • 不需載入必要旋轉:由於清單大小已知,所以不需要提醒使用者更多項目正在載入。請預留位置會自行傳送這項資訊。

不過,在新增預留位置的支援之前,請記住下列先決條件:

  • 需要可計數的資料集: DataSourceRoom 常駐資料庫才能有效計算項目。如果您使用自訂的本機儲存空間解決方案或「僅限網路的資料架構」,則可能很貴或很難確定資料集包含多少。
  • 需要轉接程式以處理未載入的項目:您用來準備資訊清單的轉接程式或表現機制必須處理空值清單項目。舉例來說,將資料繫結至 ViewHolder 時,您需要提供預設值來代表未加載的資料。
  • 需要相同大小的項目檢視:如果清單項目的大小會根據內容 (例如社交網路更新) 而改變,則相鄰的項目之間淡入淡出會看起來不太好。在這種情況下,我們強烈建議您停用預留位置。

提供意見

歡迎透過下列資源與我們分享意見和想法:

Issue Tracker
報告問題,幫助我們修正錯誤。

其他資源

如要進一步瞭解 Paging Library,請參閱下列資源。

範例

程式碼研究室

影片