このガイドはページング ライブラリの概要をベースとしており、情報のリストをアプリの UI に表示する方法について説明します。特に、情報が変更されたときの表示方法について詳しく説明します。
UI をビューモデルに接続する
次のコード スニペットに示すように、LiveData<PagedList>
のインスタンスを PagedListAdapter
に接続できます。
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) }) } }
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
は提供された特定のアイテムにバインドするだけで済みます。
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. } }
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()
を呼び出して、DataSource
から取得する必要があるアイテムに関するヒントを基盤となる PagedList
に提供します。
差分コールバックを実装する
次のサンプルは、関連するオブジェクト フィールドを比較する areContentsTheSame()
の手動による実装を示しています。
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 }
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
にリストアイテムの数を提供します。アダプターはこの情報を使用して、フルサイズのリストを反映するスクロールバーを描画します。新しいページが読み込まれてもリストのサイズは変わらないため、スクロールバーが急に大きくなることはありません。 - スピナーの読み込みが不要: リストのサイズは既知のため、追加の読み込みをユーザーに知らせる必要はありません。この情報はプレースホルダ自体から取得できます。
プレースホルダに対するサポートを追加する前に、次の前提条件を確認してください。
- カウント可能なデータセットが必要: Room 永続ライブラリの
DataSource
のインスタンスを使用することで、アイテムを効率的にカウントできます。ただし、カスタムのローカル ストレージ ソリューションまたはネットワークのみのデータ アーキテクチャを使用している場合は、コストが高くなる可能性があり、データセットを構成するアイテムの数を確認できなくなることもあります。 - 読み込みが完了していないアイテムをアダプターで処理する必要がある: null のリストアイテムは、インフレーション用のリストの準備に使用するアダプターまたはプレゼンテーション メカニズムで処理する必要があります。たとえば、データを
ViewHolder
にバインドする場合は、読み込みが完了していないデータを表すデフォルト値を指定する必要があります。 - 同じサイズのアイテムビューが必要: リストアイテムのサイズがその内容に基づいて変更される可能性がある場合(ソーシャル ネットワークの更新など)、アイテムのクロスフェードは見た目がよくありません。この場合、プレースホルダを無効にすることを強くおすすめします。
フィードバックを提供する
以下のリソースを通じてフィードバックやアイデアをお寄せください。
- Issue Tracker
- Google がバグを修正できるよう問題を報告します。
参考情報
ページング ライブラリについて詳しくは、以下のリソースをご覧ください。
サンプル
Codelab
動画
あなたへのおすすめ
Paging 2 ライブラリの概要
Discover the latest app development tools, platform updates, training, and documentation for developers across every Android device.
Paging 3 に移行する
Discover the latest app development tools, platform updates, training, and documentation for developers across every Android device.
ページング データを収集する
Discover the latest app development tools, platform updates, training, and documentation for developers across every Android device.