共通部分の実装
Pagerの実装
まずRepositoryで、PagerのインスタンスかデータソースをliveDataかFlowで返却します。
ここでは、PagingConfigを決める必要性があります。メモリ上にとどめておくデータの数を制限するといった設定もありますが、基本的な設定について3つ説明します。
pageSize
一度に読み込むデータの数、つまり1ページあたりのデータ数を指します。2列でアイテムを表示している場合などは2の倍数などで指定することが推奨されています。
この値が小さいほどメモリ使用やレイテンシが減少しますが、値が大きいほど一定時間あたりに取得できるデータ量が増えるため、厳密に設定するのであれば、ユーザーが利用している端末のスペックなどを踏まえ設定することが必要です。
prefetchDistance
すでに読み込まれたデータからどれくらい先までデータを取得するかの値です。デフォルトではpazeSizeと同じ値になっているため、基本的に触ることはないと思いますが、大きくスクロールしたときにリストの末端が見えてしまう場合などはより大きい値に設定すると解消される可能性があります。
また、0を設定すると、末端に行くまで追加読み込みを行わないという設定にすることができますが、ユーザーにプレースホルダーやリストの末端を見せることになるため推奨はされていませんが、要件によって設定しましょう。
enablePlaceholders
プレースホルダーを表示するかどうかの設定になります。デフォルトではtrueになっているため、使用しない場合はfalseを指定する必要があります。
Pagerインスタンスは以下のように返却することができます。以下のコードやサンプルコードはFlowとLiveDataの両方の使用方法を解説するためPagerインスタンスを返却していますが、Pager.flow()やPager.liveData()を指定して、PagingDataをFlowなどで返却することが一般的です。
Pagerは、pagingSourceFactoryに指定したデータソースからデータを取得し、データがなくなった場合などにremoteMediatorのload関数をトリガーしてAPIからデータを取得します。
上記の性質から、APIから取得したデータを表示するだけの場合であれば、pagingSourceFactoryにAPIの呼び出しを設定することでPagerへデータを渡すことができるので要件を達成できます。
APIから取得したデータをDBに保存してキャッシュをする場合は、pagingSourceFactoryにDBのデータを渡す関数を設定し、remoteMediatorでAPIからデータを取得しDBに保存する処理を書きます。
こうすることで、PagerはDBにキャッシュしたデータを取得し、データが不足した場合にremoteMediatorのload関数をトリガーするため、remoteMediatorがAPIからデータを取得しDBに保存するといった流れになり、要件を達成することができます。
fun getAnimes(): Pager<Int, Anime> = Pager( config = PagingConfig( pageSize = 20, prefetchDistance = 60, enablePlaceholders = false, ), pagingSourceFactory = { // 要件によって変わる部分 }, remoteMediator = // 要件によって変わる部分 )
ViewModelの実装
ViewModelでは、Repositoryの関数を呼び出してPagingDataをFragmentで値を取得できるように提供します。
// Flowの場合 fun getAnimesAsFlow(): Flow<PagingData<Anime>> = animeRepository.getAnimes().flow // LiveDataの場合 fun getAnimesAsLiveData(): LiveData<PagingData<Anime>> = animeRepository.getAnimes().liveData
PagingDataAdapterの実装
Fragmentでは、ViewModelで提供された値を取得しますが、その前にPagingのデータのクラスであるPagingDataを扱うために、PagingDataAdapterを継承したRecyclerViewのAdapterを実装します。
PagingDataAdapterを継承する以外普段のRecyclerViewのAdapterと実装は変わりありません。
まずは、PagingDataAdapterを実装する際に必要となる、リスト表示するレイアウトの実装とViewHolderの実装を行い、PagingAdapter本体の実装を見ていきます。
PagingDataAdapter実装の前準備
- RecyclerViewでリスト表示するレイアウト:RecyclerViewでリスト表示するレイアウトを定義します。今回は、アニメの画像とタイトルを表示するレイアウトを定義します。
- ViewHolder:DataBindingのBindingを持つ、RecyclerView.ViewHolderを継承したクラスを作ります。
PagingAdapter本体の実装
- DiffUtil.ItemCallback:入ってきたデータに変更があるかを確かめる処理を書きます。
- onCreateViewHolder:定義したViewHolderをインスタンス化する処理を書きます。
- onBindViewHolder:渡されたデータをレイアウトに紐づける処理を書きます。