SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

アプリケーション開発の最新トレンド

Androidのページング処理のライブラリ「Paging 3」の移行と実装のポイント

  • X ポスト
  • このエントリーをはてなブックマークに追加

共通部分の実装

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で値を取得できるように提供します。

AnimeViewModel.kt
// 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:渡されたデータをレイアウトに紐づける処理を書きます。

次のページ
共通部分の実装

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
アプリケーション開発の最新トレンド連載記事一覧

もっと読む

この記事の著者

長濱 伶(ヤフー株式会社)(ナガハマ レイ)

 2000年沖縄県生まれ。 学生時代に計算機シミュレーションを用いた文化の安定性に関する研究に従事。 2021年3月に沖縄工業高等専門学校のメディア情報工学科卒業後、4月にヤフー株式会社に入社。 2021年7月からPayPayフリマのAndroidアプリ開発に携わる。 Twitter: @Fel1Tech

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/15314 2022/02/17 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング