カテゴリー
Kotlin言語

ゼロから始めるAndroidアプリ(Kotlin編)Unit2 – 2 第3回 まとめ:RecyclerView(作成したコード)

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


Unit2 – 2 第3回 で作成した Affirmations アプリの制作手順をまとめておきますね

今回のアプリの作り方のまとめ

まずプロジェクトを作成して設定ですね

  • Android Studio 4.1 以上を起動して、新しいプロジェクトを Empty Activity として作成します
    • Name: Affirmations
    • Package: com.example.affirmations
    • Minimum SDK: API Level 19
  • いくつか新規にパッケージを作っておきます(app > java > com.example.affirmations とたどって右クリックで作成)
    • com.example.affirmations.model
    • com.example.affirmations.data
    • com.example.affirmations.adapter

アプリに表示する元データを用意

strings.xml(app > res > values > strings.xml)を次のように記述します

<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>

データをオブジェクト変換するクラスを作成

model パッケージに Affirmation.kt を作成します

package com.example.affirmations.model

data class Affirmation(val stringResourceId: Int)

データソースにまとめるクラスを作成しますね

data パッケージに Datasource.kt を作成します

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)
        )
    }
}

UI画面のレイアウトを作成します

activity_main.xml(src > main > res > layout > activity_main.xml)を次のように記述します

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        app:layoutManager="LinearLayoutManager" />

</FrameLayout>

RecyclerView で使う項目ごとのレイアウトを作成します

list_item.xml(src > main > res > layout で右クリック)を作成して次のように記述します

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

アダプタのクラスを作成しますね

adapter パッケージに ItemAdapter.kt を作成します

package com.example.affirmations.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.affirmations.R
import com.example.affirmations.model.Affirmation

/**
 * Adapter for the [RecyclerView] in [MainActivity]. Displays [Affirmation] data object.
 */
class ItemAdapter(
    private val context: Context,
    private val dataset: List<Affirmation>
) : RecyclerView.Adapter<ItemAdapter.ItemViewHolder>() {

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder.
    // Each data item is just an Affirmation object.
    class ItemViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
        val textView: TextView = view.findViewById(R.id.item_title)
    }

    /**
     * Create new views (invoked by the layout manager)
     */
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
        // create a new view
        val adapterLayout = LayoutInflater.from(parent.context)
            .inflate(R.layout.list_item, parent, false)

        return ItemViewHolder(adapterLayout)
    }

    /**
     * Replace the contents of a view (invoked by the layout manager)
     */
    override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
        val item = dataset[position]
        holder.textView.text = context.resources.getString(item.stringResourceId)
    }

    /**
     * Return the size of your dataset (invoked by the layout manager)
     */
    override fun getItemCount() = dataset.size
}

最後に MainActivity クラスを仕上げます

MainActivity.kt を次のように記述します

package com.example.affirmations

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import com.example.affirmations.adapter.ItemAdapter
import com.example.affirmations.data.Datasource

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Initialize data.
        val myDataset = Datasource().loadAffirmations()

        val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
        recyclerView.adapter = ItemAdapter(this, myDataset)

        // Use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        recyclerView.setHasFixedSize(true)
    }
}

これで完成ですね!

うん、ばっちり。ビルドして動かしてみてくださいね

まとめ

長かったですね、おつかれさまでした

  • RecyclerView はリストになったデータを表示するのに便利です
  • RecyclerView はデータを適用して表示するのにアダプタパターン(Adapter Pattern)と呼ばれる設計手法を使っています
  • RecyclerView で表示されるリスト内の項目ひとつひとつは、ビューホルダーという考え方で扱います
  • RecyclerView ではAndroidフレームワークに用意されている LayoutManager を使って配置を行っています

アダプタの作り方

  • アダプタは抽象クラス RecyclerView.Adapter のサブクラスとして作成します
  • アダプタには、内部にビューホルダーのクラスを作成します
  • ビューホルダーは抽象クラス RecyclerView.ViewHolder のサブクラスとして作成します
  • アダプタには次の3つのメソッド(親クラスで定義されている抽象メソッド)を必ずオーバーライドで実装します
    • getItemsCount()onCreateViewHolder()onBindViewHolder()

データソースの作り方

  • RecyclerView に表示したいデータのひとつひとつをオブジェクトに変換するクラスを作成します
  • 変換で作られたデータオブジェクトをリストにまとめて返すクラスを作成します
  • このデータオブジェクトがリストになったものをデータソースとします

参考