SHOEISHA iD

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

連載記事

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

翔泳社では、「独習」「徹底入門」「スラスラわかる」「絵で見てわかる」「一年生」などの人気シリーズをはじめ、言語や開発手法、最新技術を解説した書籍を多数手がけています。プロジェクトマネジメントやチームビルティングといった管理職向けの書籍も豊富です。

ITエンジニアとしてのスキルアップ・リスキリングに、ぜひお役立てください。

書籍に関する記事を見る

'); googletag.cmd.push(function() { googletag.pubads().addEventListener('slotRenderEnded', function(e) { var ad_id = e.slot.getSlotElementId(); if (ad_id == 'div-gpt-ad-1659428980688-0') { var ad = $('#'+ad_id).find('iframe'); if ($(ad).width() == 728) { var ww = $(window).width(); ww = ww*0.90; var style = document.createElement("style"); document.head.appendChild( style ); var sheet = style.sheet; sheet.insertRule( "#div-gpt-ad-1659428980688-0 iframe {-moz-transform: scale("+ww/728+","+ww/728+");-moz-transform-origin: 0 0;-webkit-transform: scale("+ww/728+","+ww/728+");-webkit-transform-origin: 0 0;-o-transform: scale("+ww/728+","+ww/728+");-o-transform-origin: 0 0;-ms-transform: scale("+ww/728+","+ww/728+");-ms-transform-origin: 0 0;}", 0 ); sheet.insertRule( "#div-gpt-ad-1659428980688-0 div{ height:"+(90*ww/728)+"px;width:"+728+"px;}", 0 ); } else { if ($(window).width() < 340) { var ww = $(window).width(); ww = ww*0.875; var style = document.createElement("style"); document.head.appendChild( style ); var sheet = style.sheet; sheet.insertRule( "#div-gpt-ad-1659428980688-0 iframe {-moz-transform: scale("+ww/320+","+ww/320+");-moz-transform-origin: 0 0;-webkit-transform: scale("+ww/320+","+ww/320+");-webkit-transform-origin: 0 0;-o-transform: scale("+ww/320+","+ww/320+");-o-transform-origin: 0 0;-ms-transform: scale("+ww/320+","+ww/320+");-ms-transform-origin: 0 0;}", 0 ); sheet.insertRule( "#div-gpt-ad-1659428980688-0 div{ height:"+(180*ww/320)+"px;width:"+320+"px;}", 0 ); } } } }); }); } else { document.write('
'); document.write('
'); }
一歩進んだAndroidアプリ開発ができる「Android Jetpack」入門

「ページングライブラリ」でネット上のリストデータをページングする方法

一歩進んだAndroidアプリ開発ができる「Android Jetpack」入門 第13回

 本連載は、「Android Studio2で始めるアプリ開発入門」連載、および『Androidアプリ開発の教科書』の続編にあたる内容として、Jetpackを取り上げていきます。前回は、大量のデータを効率よく表示できるページングライブラリの基礎的な使い方を解説しました。今回は、ページングライブラリを利用してネット上にあるリストデータをページングする方法を紹介します。

PagingSourceクラスの自作が必要(1)

 本連載は、Android Jetpackを紹介しています。今回は、大量のデータを効率よく扱えるページングライブラリを利用して、ネット上にあるリストデータをページングする方法を解説します。

 なお、今回のサンプルデータは、GitHubから参照できます。ただし、サンプル内のコードでは実際にネットにアクセスしてデータを取得するコードは記載せず、ダミーでデータを生成するコードとなっている点はあらかじめご了承ください。

PagingSourceクラスはPagingSourceを継承

 前回紹介したのは、大量のリストデータをページに分割し、その制御を行うPagingSourceオブジェクトを、Roomによって自動生成してもらうといった内容でした。大量のリストデータがデータベース内に格納されているならば、この方法が最適といえます。

 一方、データがネット上にある場合、当然ですがRoomによる自動生成は使えず、PagingSourceクラスを自作し、その中でネットからデータを取得するコードを記述する必要があります。その骨格は、例えば、リスト1のコードになります。このコードは、前回の図1同様に、電話番号とその主キーを表示するアプリを想定しています。そのため、クラス名をPhonePagingSourceとしています。

[リスト1]PagingSourceクラスの骨格
class PhonePagingSource : PagingSource<Int, Phone>() {  // (1)
  override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Phone> {  // (2)
    :
  }
  override fun getRefreshKey(state: PagingState<Int, Phone>): Int? {  // (3)
    :
  }
}

 PagingSourceクラス作成のポイントは、(1)にあるように、PagingSourceクラスを継承することです。その際、ジェネリクスとして、RoomのDAOインターフェースのリストデータを取得するメソッドの戻り値のPagingSourceに定義したジェネリクスと同様のものを指定します。すなわち、ジェネリクスのひとつめは、各ページを区別するためのデータのデータ型を、ふたつめはリストデータの各アイテムを表すクラスを指定します。

 このPagingSourceクラスは抽象クラスとなっているので、抽象メソッドをオーバーライドしておく必要があります。それが、リスト1の(2)のload()と(3)のgetRefreshKey()です。

load()メソッドの実装方法

 オーバーライドが必要な2個の抽象メソッドのうち、load()メソッドはページングの肝となるメソッドです。その引数であるLoadParamsには、表1の3個のプロパティが含まれています。なお、表中のデータ型Keyはジェネリクスで指定したデータ型です。

表1:LoadParamsのプロパティ
プロパティ名 データ型 内容
key Key? 次に読み込むべきリストのキーとなる値。初回時はnull
loadSize Int 1ページ分のアイテム数
placeholdersEnabled Boolean PagingConfig.enablePlaceholdersで設定した値

 これらの値を元に、ネットなどから必要なリストデータを取得し、そのリストデータを元にページデータを生成してリターンします。その戻り値としては、無事リストデータが用意できた場合はLoadResult.Pageを、失敗した場合はLoadResult.Errorとします。

 これは、例えば、リスト2のコードとなります。なお、(2)のfetchPhoneListSize()は、ネット上にあるリストデータの総件数を取得するsuspend関数です。同様に、fetchPhoneList()は、ネット上からリストデータを取得するsuspend関数です。引数としては切り出すリストの開始idと終了idを受け取るようにしています。

[リスト2]load()メソッドのコード例
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Phone> {
  var returnVal: LoadResult<Int, Phone>  // (1)
  try {
    val phoneListSize = fetchPhoneListSize()  // (2)
    val startKey = params.key ?: 1  // (3)
    var endKey = startKey + params.loadSize - 1  // (4)
    if(endKey > phoneListSize) {  // (4)
      endKey = phoneListSize
    }
    val fetchedPhoneList = fetchPhoneList(startKey, endKey)  // (5)
    val prevKey = if(startKey - params.loadSize <= 0) {  // (6)
      null
    }
    else {
      startKey - params.loadSize
    }
    val nextKey = if(endKey + 1 >= phoneListSize) {  // (7)
      null
    }
    else {
      endKey + 1
    }
    returnVal = LoadResult.Page(fetchedPhoneList, prevKey, nextKey)  // (8)
  }
  catch(ex: Exception) {
    returnVal = LoadResult.Error(ex)  // (9)
  }
  return returnVal
}

 リスト2の大きな流れとしては、(1)で戻り値変数としてLoadResult<Int, Phone>型のreturnValを用意し、その後、処理全体をtryブロックで囲み、例外処理を行っています。ネット上からデータを取得するような処理では必須のコードパターンといえます。

 その例外処理のcatchブロックが処理失敗と言えるので、(9)でLoadResult.Errorインスタンスを生成し、戻り値のreturnValとしています。その際、引数として例外インスタンスを渡しています。

 一方、tryブロックの最終行である(8)が処理が成功した場合ですので、そこでLoadResult.Pageインスタンスを生成しています。その際、引数として表2の3個の値を渡す必要があり、これらを事前にtryブロック内で用意しています。なお、表中のデータ型KeyとValueはジェネリクスで指定したデータ型です。

表2:LoadParamsのプロパティ
引数名 データ型 内容
1 data List<Value> 現在のページのリストデータ
2 prevKey Key? 前ページの開始キーの値。前ページがない場合はnull
3 nextKey Key? 次ページの開始キーの値。次ページがない場合はnull

 まず、(3)~(5)でネット上からリストデータを取得しています。(3)が開始キー、すなわち、ネット上にあるリストデータから切り出すリストデータの開始idを、変数startKeyとして生成しています。その際、引数paramsのkeyプロパティの値を利用し、表1の通り、この値がnullの場合は1としています。

 (4)は、終了キーをendKeyとして生成しています。その際、表1の引数paramsのloadSizeプロパティを利用しています。さらに(2)で取得した全リストサイズを元にendKeyがリストサイズを超えている場合は、endKeyをリストサイズとしています。

 このようにして生成したstartKeyとendKeyを元にネット上からリストデータを取得しているのが(5)です。そして、これがそのまま(8)でLoadResult.Pageインスタンスを生成する際の第1引数となっています。

 次に、第2引数のprevKeyと第3引数のnextKeyを生成しておく必要があります。それが(6)と(7)です。これらのコードは、単純にstartKeyやendKeyとparams.loadSizeを元に算出する処理に過ぎません。ただし、表2の通り、prevKeyの場合は、算出した結果が0以下の場合は前ページがないのでnullとする必要があります。同様に、nextKeyは全リストサイズより大きければnullとする必要があります。

会員登録無料すると、続きをお読みいただけます

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

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます
  • ・翔泳社の本が買える!
    500円分のポイントをプレゼント

メールバックナンバー

次のページ
PagingSourceクラスの自作が必要(2)

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

一歩進んだAndroidアプリ開発ができる「Android Jetpack」入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)

<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。

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

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/21204 2025/03/27 11:00
" ); }

おすすめ

アクセスランキング

  1. 1
    GitHub Copilot BusinessとProでClaudeとCodexが利用可能に
  2. 2
    Google Workspaceで直近発表された新機能をまとめて紹介 NEW
  3. 3
    ITエンジニア本大賞 2026の最終プレゼンをレポート 栄冠に輝いた著者が語る本の魅力
  4. 4
    パナソニックはなぜ開発環境の「文房具化」に挑んだのか──グループ横断で進めた開発環境改革の舞台裏
  5. 5
    「REPL」 ~マンガでプログラミング用語解説
  1. 6
    VSCodeでPHP開発環境を構築しよう
  2. 7
    Notion、ページをフルスクリーンプレゼンテーションにする新機能を発表 NEW
  3. 8
    GitHub CopilotがClaude Opus 4.1、GPT-5、GPT-5-Codexの非推奨を発表
  4. 9
    プログラミング問題集「Exercise」シリーズ全5冊が3/10まで半文公開 C++、JS、Pyhon、Go、Rustもあり NEW
  5. 10
    Perplexity、複数のAI機能を単一のシステムに統合する「Perplexity Computer」リリース NEW

アクセスランキング

  1. 1
    GitHub Copilot BusinessとProでClaudeとCodexが利用可能に
  2. 2
    Google Workspaceで直近発表された新機能をまとめて紹介 NEW
  3. 3
    ITエンジニア本大賞 2026の最終プレゼンをレポート 栄冠に輝いた著者が語る本の魅力
  4. 4
    パナソニックはなぜ開発環境の「文房具化」に挑んだのか──グループ横断で進めた開発環境改革の舞台裏
  5. 5
    「REPL」 ~マンガでプログラミング用語解説
  6. 6
    VSCodeでPHP開発環境を構築しよう
  7. 7
    Notion、ページをフルスクリーンプレゼンテーションにする新機能を発表 NEW
  8. 8
    GitHub CopilotがClaude Opus 4.1、GPT-5、GPT-5-Codexの非推奨を発表
  9. 9
    プログラミング問題集「Exercise」シリーズ全5冊が3/10まで半文公開 C++、JS、Pyhon、Go、Rustもあり NEW
  10. 10
    Perplexity、複数のAI機能を単一のシステムに統合する「Perplexity Computer」リリース NEW
  1. 1
    GitHub CopilotがClaude Opus 4.1、GPT-5、GPT-5-Codexの非推奨を発表
  2. 2
    【速報】ITエンジニア本大賞 2026、技術書部門とビジネス書部門の大賞が決定!
  3. 3
    「LTSとSTS」 ~マンガでプログラミング用語解説
  4. 4
    GitHub、Markdownで目標を記述することでタスクを自動実行する「Agentic Workflows」公開
  5. 5
    「否定された」と感じさせないコードレビューの作法。チームを育てるテキストコミュニケーションとは?
  6. 6
    Claude Skillsとは? AIエージェント開発における新たなベストプラクティスをやさしく解説
  7. 7
    「REPL」 ~マンガでプログラミング用語解説
  8. 8
    C++の新機能を理解する──静的なoperator()/operator[]と多次元対応operator[]など言語仕様の強化
  9. 9
    最新バージョン.NET 10/Visual Studio 2026の登場が、開発者にいかなる価値をもたらすか──「ECHO 2025」開催
  10. 10
    Apple、2026年4月からiOSアプリの新SDK対応を必須化

イベント

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

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

メールバックナンバー

アクセスランキング

  1. 1
    GitHub Copilot BusinessとProでClaudeとCodexが利用可能に
  2. 2
    Google Workspaceで直近発表された新機能をまとめて紹介 NEW
  3. 3
    ITエンジニア本大賞 2026の最終プレゼンをレポート 栄冠に輝いた著者が語る本の魅力
  4. 4
    パナソニックはなぜ開発環境の「文房具化」に挑んだのか──グループ横断で進めた開発環境改革の舞台裏
  5. 5
    「REPL」 ~マンガでプログラミング用語解説
  1. 6
    VSCodeでPHP開発環境を構築しよう
  2. 7
    Notion、ページをフルスクリーンプレゼンテーションにする新機能を発表 NEW
  3. 8
    GitHub CopilotがClaude Opus 4.1、GPT-5、GPT-5-Codexの非推奨を発表
  4. 9
    プログラミング問題集「Exercise」シリーズ全5冊が3/10まで半文公開 C++、JS、Pyhon、Go、Rustもあり NEW
  5. 10
    Perplexity、複数のAI機能を単一のシステムに統合する「Perplexity Computer」リリース NEW

アクセスランキング

  1. 1
    GitHub Copilot BusinessとProでClaudeとCodexが利用可能に
  2. 2
    Google Workspaceで直近発表された新機能をまとめて紹介 NEW
  3. 3
    ITエンジニア本大賞 2026の最終プレゼンをレポート 栄冠に輝いた著者が語る本の魅力
  4. 4
    パナソニックはなぜ開発環境の「文房具化」に挑んだのか──グループ横断で進めた開発環境改革の舞台裏
  5. 5
    「REPL」 ~マンガでプログラミング用語解説
  6. 6
    VSCodeでPHP開発環境を構築しよう
  7. 7
    Notion、ページをフルスクリーンプレゼンテーションにする新機能を発表 NEW
  8. 8
    GitHub CopilotがClaude Opus 4.1、GPT-5、GPT-5-Codexの非推奨を発表
  9. 9
    プログラミング問題集「Exercise」シリーズ全5冊が3/10まで半文公開 C++、JS、Pyhon、Go、Rustもあり NEW
  10. 10
    Perplexity、複数のAI機能を単一のシステムに統合する「Perplexity Computer」リリース NEW
  1. 1
    GitHub CopilotがClaude Opus 4.1、GPT-5、GPT-5-Codexの非推奨を発表
  2. 2
    【速報】ITエンジニア本大賞 2026、技術書部門とビジネス書部門の大賞が決定!
  3. 3
    「LTSとSTS」 ~マンガでプログラミング用語解説
  4. 4
    GitHub、Markdownで目標を記述することでタスクを自動実行する「Agentic Workflows」公開
  5. 5
    「否定された」と感じさせないコードレビューの作法。チームを育てるテキストコミュニケーションとは?
  6. 6
    Claude Skillsとは? AIエージェント開発における新たなベストプラクティスをやさしく解説
  7. 7
    「REPL」 ~マンガでプログラミング用語解説
  8. 8
    C++の新機能を理解する──静的なoperator()/operator[]と多次元対応operator[]など言語仕様の強化
  9. 9
    最新バージョン.NET 10/Visual Studio 2026の登場が、開発者にいかなる価値をもたらすか──「ECHO 2025」開催
  10. 10
    Apple、2026年4月からiOSアプリの新SDK対応を必須化