カテゴリー
Kotlin言語

ゼロから始めるAndroidアプリ(Kotlin編)Unit2 – 2 第3回 前半:RecyclerView(データソースの作成)

Android Developers > スタートガイド > Kotlin と Android をゼロから学ぶ > Unit2 – レイアウトUnit2-2 第3回 前半 の内容をまとめたものです(翻訳ではありません)


Unit2 – 2 第3回

RecyclerView とは

  • RecyclerView はリストデータを画面に表示するためのUI部品(View)です
  • RecyclerView は、スクロールで画面からはずれた View を自動的に再利用(recycling)します。大きなリストデータでも効率的に動作するようになっています
  • ここではテキストデータのリストを RecyclerView で表示してみます

このレッスンでつくるアプリ

  • Affirmations app(元気がでるテキストメッセージが表示されるアプリ)をつくってみます
  • Affirmations app ではテキストメッセージを10個、スクロールできる形で表示します
  • テキストメッセージをリストで表示するのに RecyclerView を使います
  • RecyclerView のアダプタ(Adapter)を設定して、リストのデザインをカスタマイズしてみます
  • パッケージ(package)を使ってKotlinコードを機能ごとに分けてみます

RecyclerView の基本

ちょっとややこしいので、これからやることを簡単にまとめておきますね

RecyclerView の基本用語

  • RecyclerView ・・・リストデータを表示するUI部品
  • ビューホルダー(ViewHolder)・・・RecyclerView が扱うひとつひとつの項目のこと
  • アダプタ(Adapter)・・・ビューホルダーを管理するオブジェクト
  • データソース・・・RecyclerView で扱えるようにオブジェクト化したデータ(データモデル)をリスト形式にしたもの
  • アイテム(item)・・・ビューホルダーによってUI画面に実際に表示される項目のこと

RecyclerView を使ったUI画面の基本構造

RecyclerView
    ViewHolder A
    ViewHolder B
    ViewHolder C
    ・・・

RecyclerView のしくみ

表示したい項目の入ったリストをアダプタ(Adapter)が読み取って、ビューホルダー(ViewHolder)と呼ばれる表示バッファに必要な部分だけセットし、UI画面に設置した RecyclerView に送り出します

うまく設定をしてあげれば、だいたいのことは RecyclerView がやってくれるんですね

RecyclerView の使い方のポイント

  1. データソースを準備する(データはオブジェクト化した上でリスト化しておく)
  2. アダプタ(Adapter)に、ビューホルダー(ViewHolder)を操作するための記述をする
  3. RecyclerView で表示する

この RecyclerView チュートリアルで作成するファイル

いろいろ作るんですね

UI画面のレイアウト

  • RecyclerView を表示するためのレイアウト・・・activity_main.xml に記述
  • ビューホルダー(アイテム)を表示するためのレイアウト・・・今回は list_item.xml というファイルに記述

動作させるためのコード

  • アダプタのコード・・・今回は ItemAdapter.kt(ItemAdapterクラス)に記述
  • アプリのコード・・・MainActivity.kt(MainActivityクラス)に記述

表示するデータ

  • 元データ・・・今回は strings.xml に用意
  • オブジェクト化したデータ・・・今回は Affirmation.kt(Affirmationクラス)によって生成する
  • データソース・・・今回は Datasource.kt(Datasourceクラス)によって生成する

この RecyclerView チュートリアルで記述するコード

これから進めるチュートリアルの中で、ひとつひとつ解説しています

データソースの作成

  1. 元になるデータを用意する・・・今回は R.string.名前(strings.xml)
  2. ひとつひとつのデータをオブジェクト化する・・・今回は Affirmation.kt(Affirmationクラス)で行います
  3. データのオブジェクトをリスト化する・・・今回は Datasource.kt(Datasourceクラス)で行います

アダプタの作成

アダプタのクラスを作成する・・・今回は ItemAdapter.kt(ItemAdapterクラス)とします。抽象クラス RecyclerView.Adapter のサブクラスとして作成します

  • ビューホルダーのクラスを作成します・・・今回は ItemViewHolder クラスという名前にします
    • 抽象クラス RecyclerView.ViewHolder のサブクラスとして作成します
    • ビューホルダー(アイテム)のレイアウト(今回は list_item.xml)にあるUI部品への参照をプロパティとして用意します
  • onCreateViewHolder() をオーバーライド
    • ビューホルダーを生成するメソッドです
    • ビューホルダー(アイテム)のレイアウト(今回は list_item.xml)を使うようにコードを記述します
  • onBindViewHolder()
    • ビューホルダーへ表示データを設定するメソッドです
    • ビューホルダーのプロパティを使ってUI部品にデータをセットするコードを記述します
  • getItemCount()・・・データソース(今回はDatasourceオブジェクト)の中のデータ数を設定します

RecyclerView で表示するコード(MainActivity.kt に記述します)

  1. データソースを取得する・・・今回は Datasource オブジェクトの loadAffirmations() メソッドを使って取得します
  2. RecyclerView にアダプタを設置する・・・データソースを渡します

それでは頑張ってはじめますね

プロジェクトの作成

Android Studio は 4.1 以上がおすすめです

  • Android Studio を起動して、新しいプロジェクトを Empty Activity として作成します
    • Name: Affirmations
    • Package: com.example.affirmations
    • Minimum SDK: API Level 19
  • このプロジェクトでは Material の Components と theme を使います
    • Android Studio 4.1 以降であれば設定は不要です
    • それ以前のAndroid Studioでは設定が必要です。モジュールの build.gradle をひらいて dependencies の項目を修正します(詳しくは Unit 2-1 の第6回

データソースの作成

データは扱いやすくするためにオブジェクト化しちゃうんです

元データを用意する

  • Androidアプリの画面に表示されるメッセージは、データベースやインターネット上のサーバから取得することがあります。
  • 今回はコードを簡単にするため、テキストメッセージをアプリ内(strings.xml)で用意することにします

strings.xml に表示したいテキストメッセージを追加する

  1. Project で strings.xml を開きます(app > res > values > strings.xml
  2. affirmation1affirmation2 ・・・ という文字列リソースを追加します

こんな感じになります

<resources>
    <string name="app_name">Affirmations</string>
    <string name="affirmation1">I am strong.</string>
    <string name="affirmation2">I believe in myself.</string>
    <string name="affirmation3">Each day is a new opportunity to grow and be a better version of myself.</string>
    <string name="affirmation4">Every challenge in my life is an opportunity to learn from.</string>
    <string name="affirmation5">I have so much to be grateful for.</string>
    <string name="affirmation6">Good things are always coming into my life.</string>
    <string name="affirmation7">New opportunities await me at every turn.</string>
    <string name="affirmation8">I have the courage to follow my heart.</string>
    <string name="affirmation9">Things will unfold at precisely the right time.</string>
    <string name="affirmation10">I will be present in all the moments that this day brings.</string>
</resources>

strings.xml に追加されたテキストメッセージをKotlinコードから参照するには、Rクラスを使って R.string.affirmation1 のようにします

元データの準備ができました

パッケージを作っておく

今回はKotlinコードを機能別にパッケージに分けて管理しますね

新規にパッケージ(package)を作成する

  • データをオブジェクト化するためのクラス(Affirmationクラス)を新しく作ったパッケージに登録してみます
  • アプリ(MainActivityクラス)はプロジェクト作成時に com.example.affirmations パッケージに登録されています
  • 新規に com.example.affirmations.model パッケージを作成してみます

パッケージの作成

  1. Android Studio を起動して、Project で表示を Android にしておきます
  2. app > java とたどると、com.example.affirmations というパッケージがあるので右クリックします
  3. New > Package と選択すると New Package というポップアップが出ます
  4. com.example.affirmations.model と入れてEnterを押します
  5. com.example.affirmations の下に model が追加されます
    • データに関連したクラスのパッケージ名に model はよく使われます
    • このパッケージにアプリのデータに関連したクラスを入れることにします

パッケージできました

パッケージの使い方

  • パッケージの利用法は2通りあります
    • 利用法1:他のパッケージからコードを読み込んで利用するのに使います。import 文を使って宣言することもあります
    • 利用法2:アプリのコードを機能別に分類しておくために利用します。たとえばデータ用のクラスとUI画面用のクラスを別のパッケージにして管理しやすくします(今回はこちらです)
  • アプリに作成したクラスが多くなくても、クラスは機能ごとにパッケージに分類しておくことをお勧めします

パッケージ名のつけ方

  • パッケージ名は何でも構わないんですが、世界で唯一のもの、重複しないものにします
  • 適当につけた名前では重複しないとは限らないので、インターネットのドメイン名を使って命名します
    • ドメイン名を逆さまにして並べます。たとえば kommkett.co.jp なら jp.co.kommkett とします。逆さまにするのは、指定を広い範囲からだんだん狭い範囲にしていくためです
    • 最後にアプリの名前をつけます。アプリの名前が Affirmations ならば jp.co.kommkett.affirmations です。アルファベットはすべて小文字にします
  • パッケージ名のピリオドは、単なる名前の一部で意味はありません。ディスク上のフォルダーとも関係がなく、階層関係をあらわしているわけでもありません。分かりやすさのためにフォルダの階層と一致させていることもあるけれど、一致している保証はありません
  • パッケージの内容や、パッケージ同士の関係などが分かるように自由につけて構いません。パッケージ名のピリオドに階層の意味はないんですが、階層的に命名して関係を分かりやすくするのはお勧めです

パッケージ名が違っても、入ってるフォルダは同じだったりするんですね

データをオブジェクト化する

元データをオブジェクトに変換するクラスを作成しますね

  • データをオブジェクト化するのに Affirmation という名前のクラスを作成します
  • Affirmation クラスを使って、元データ(テキストメッセージ)ひとつを、Affirmation クラスのインスタンスひとつに置き換えます
  • 今回は Affirmation インスタンスが strings.xml にあるテキストメッセージのリソースIDを持つようにします

Affirmation クラスを作成する

Affirmation クラスは model パッケージに入れます

  1. Android Studio の Project で com.example.affirmations.model を右クリックします
  2. New > Kotlin File/Class を選択します
  3. ポップアップが出たら Class を選択、クラス名に Affirmation と入力して Enter を押します
  4. model パッケージに Affirmation.kt ファイルが作成されます

Affirmation クラスの内容を記述する

  • Affirmation.kt を開いて data キーワードを使ってデータクラスを作成します
  • データクラスには少なくともひとつプロパティが必要なのでエラーが出ます。修正するのでそのままにしておきます
package com.example.affirmations.model

data class Affirmation {
}

Affirmation クラスの引数(コンストラクタ)にはテキストメッセージのリソースID(整数)を渡します

package com.example.affirmations.model

data class Affirmation(val stringResourceId: Int)

リソースIDを渡すための変数として stringResourceID を設定しています。プロパティがひとつ宣言されたのでエラーは消えます

Affirmation クラスはこれで完成です

データソースになるクラスを作成する

オブジェクトにしたデータをリストにまとめるクラスを作りますね

  • 元データを Affirmation クラスでインスタンス化したものをDatasource という名前のクラスを使ってひとつのリストにまとめます
    • データをインスタンスのリストにすることで、元データがどんなものであっても同じように扱うことができます
    • また、アプリの他のクラスにとって、データが元々どんなものであったのかは隠蔽されており関心もありません
    • クラスが関心をもつ内容が異なる場合は分けて扱うと分かりやすくなります(関心の分離:separation of concerns、SoC)
  • Datasource クラスは、新規に作成する data というパッケージに作成してみます

新規パッケージ data を作成する

Datasource クラスは data パッケージにします

  1. Android Studio を起動して、Project で app > java > com.example.affirmations とたどって右クリックします
  2. New > Package を選択します
  3. パッケージ名の最後の部分を data としてパッケージを作成します

Datasource クラスを作成する

  1. Project で、作成した data パッケージを右クリックします
  2. new Kotlin File/Class を選択します
  3. クラス名として Datasource と入力して Enter を押します
  4. Datasource.kt が作成されてファイルが開きます

Datasource クラスの内容を記述する

  • Datasource クラスの中に loadAffirmations() メソッドを作成します
  • loadAffirmations() メソッドは Affirmation インスタンスのリストを返します
package com.example.affirmations.data

import com.example.affirmations.R
import com.example.affirmations.model.Affirmation


class Datasource {

    fun loadAffirmations(): List<Affirmation> {
        return listOf<Affirmation>(
            Affirmation(R.string.affirmation1),
            Affirmation(R.string.affirmation2),
            Affirmation(R.string.affirmation3),
            Affirmation(R.string.affirmation4),
            Affirmation(R.string.affirmation5),
            Affirmation(R.string.affirmation6),
            Affirmation(R.string.affirmation7),
            Affirmation(R.string.affirmation8),
            Affirmation(R.string.affirmation9),
            Affirmation(R.string.affirmation10)
        )
    }
}
  • loadAffirmations() メソッドの戻り値は List<Affirmation> 型です
  • Affirmation のコンストラクタにテキストメッセージのリソースIDを渡すことで、Affirmation インスタンスの stringResourceId プロパティにリソースIDがセットされます

これで RecyclerView で使うデータソースの準備はばっちりですね

動作テスト:TextView を追加してデータソースのサイズを表示してみる

ここまでのコードがちゃんと動くかテストしておきますね

  • データソースが作成できるようになったので動作テストをしてみます
  • Datasource クラスを使ってデータのインスタンスのリストを作成してみます。得られたリストの要素数を TextView に表示してみます

activity_main.xml に TextView を追加する

UI画面(activity_main.xml)に TextView を追加します(idはtextview)

MainActivity.kt にテスト用のコードを追加する

MainActivity.kt の onCreate() メソッドに次のコードを書き込みます

val textView: TextView = findViewById(R.id.textview)
textView.text = Datasource().loadAffirmations().size.toString()

アプリを実行してみる

  • 画面に strings.xml に設定したテキストメッセージの数(10)が表示されれば成功です
  • 動作テストが終わったら、テスト用に追加した TextView と MainActivity.kt に追加したコードは消しておきます

テスト用のコードは、テストが終わったら消しちゃっていいんですね