LoginSignup
1
0

More than 3 years have passed since last update.

RecyclerViewでリスト表示を実装する

Posted at

やりたいこと

RecyclerViewを使用して、あるデータをリスト表示するシンプルなアプリです。

Screenshot_1614933541.png

環境

Android Studio: 4.1.1
Kotlin: 1.4.10

実装

データクラスを作成する

表示する情報のデータクラスを作成します。
classの前にdataをつけることでデータクラスとして作成されます。
今回はFruitという名前にしています。

Fruit.kt
data class Fruit(
    var name: String,
    var imageId: Int
)

アイテムのレイアウトファイルを作成する

次に、RecyclerView内にリスト表示される1つ1つのアイテムのレイアウトファイルを作成します。

list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_marginTop="18dp"
        android:layout_marginEnd="18dp"
        android:layout_marginStart="18dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/fruit_name"
        tools:src="@drawable/apple" />

    <TextView
        android:id="@+id/fruit_name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="4dp"
        android:layout_marginEnd="4dp"
        android:textSize="24sp"
        app:layout_constraintStart_toEndOf="@id/fruit_image"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@id/fruit_image"
        app:layout_constraintBottom_toBottomOf="@id/fruit_image"
        tools:text="apple" />

</androidx.constraintlayout.widget.ConstraintLayout>

レイアウトにRecyclerViewを設置する

このアプリでは、一部データバインディングを使用するので、アプリモジュールのbuild.gradledataBindingを追加します。

build.gradle(:app)

android {
        ...
        dataBinding {
            enabled = true
        }
    }

RecyclerViewにはリストの表示方法を設定するlayoutManagerが必須なので、忘れないように注意が必要です。

fragment_fruit.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".FruitFragment">

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

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Adapterを作成する

1. Adapterクラスの作成

FruitAdapter.kt
class FruitAdapter: RecyclerView.Adapter<FruitAdapter.ViewHolder>() {
}

class FruitAdapterにカーソルを合わせ、option+Enter(Macの場合) -> Implement membersを選択することで、Adapterクラスに必要な3つのメソッドを自動で生成してくれます。

FruitAdapter.kt
class FruitAdapter: RecyclerView.Adapter<FruitAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitAdapter.ViewHolder {
        TODO("Not yet implemented")
    }

    override fun onBindViewHolder(holder: FruitAdapter.ViewHolder, position: Int) {
        TODO("Not yet implemented")
    }

    override fun getItemCount(): Int {
        TODO("Not yet implemented")
    }
}

onCreateViewHolder:新しいViewHolderを作成する必要があるたびに呼ばれる。Viewを生成して、ViewHolderを返す。
onBindViewHolderpositionから適切なデータを取得して、各アイテムのレイアウトと関連付ける。
getItemCount:表示するアイテム数を設定する。

2. ViewHolderを作成

まだViewHolderを作成していないため、<FruitAdapter.ViewHolder>の部分でエラーが出るので、FruitAdapterクラス内にViewHolderを作成します。

FruitAdapter.kt
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val fruitName: TextView = itemView.findViewById(R.id.fruit_name)
        val fruitImage: ImageView = itemView.findViewById(R.id.fruit_image)
}

3. Adapterクラス内の実装

  • データを保持する変数を作成
FruitAdapter.kt
var data = ArrayList<Fruit>()
  • getItemCount()

この値がRecyclerView内に表示されるアイテムの数になります。

FruitAdapter.kt
override fun getItemCount() = data.size
  • onBindViewHolder()

onBindViewHolder()関数では、positionから取得した適切なデータを、textViewなどに設定します。

FruitAdapter.kt
override fun onBindViewHolder(holder: FruitAdapter.ViewHolder, position: Int) {
        val item = data[position]

        holder.fruitName.text = item.name
        holder.fruitImage.setImageResource(item.imageId)
    }
  • onCreateViewHolder()

layoutInflaterでViewを作成して、ViewHolderを返します。

FruitAdapter.kt
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitAdapter.ViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val view = layoutInflater.inflate(R.layout.list_item, parent, false)
        return ViewHolder(view)
    }

コード

最終的にこのようになれば、Adapterクラスの完成です。

FruitAdapter.kt
class FruitAdapter: RecyclerView.Adapter<FruitAdapter.ViewHolder>() {

    var data = ArrayList<Fruit>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitAdapter.ViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val view = layoutInflater.inflate(R.layout.list_item, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: FruitAdapter.ViewHolder, position: Int) {
        val item = data[position]

        holder.fruitName.text = item.name
        holder.fruitImage.setImageResource(item.imageId)
    }

    override fun getItemCount() = data.size

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val fruitName: TextView = itemView.findViewById(R.id.fruit_name)
        val fruitImage: ImageView = itemView.findViewById(R.id.fruit_image)
    }
}

RecyclerViewにAdapterを設定する

Adapterの設定は全てonCreateView()メソッド内で行います。
(アクティビティの場合は、onCreate()メソッド)

1. Adapterを初期化する

FruitFragment
val adapter = FruitAdapter()

2. データを格納する

今回はサンプルなので、あらかじめ用意したデータを表示させるようにしています。
基本的にはデータベース等から取得した動的なデータを使ったりすると思います。

FruitFragment
val adapter = FruitAdapter()

val fruitData = arrayListOf(
            Fruit("Apple", R.drawable.apple),
            Fruit("Banana", R.drawable.banana),
            Fruit("Cherry", R.drawable.cherry),
            Fruit("Grape", R.drawable.grape),
            Fruit("Orange", R.drawable.orange),
            Fruit("Peach", R.drawable.peach),
            Fruit("Pineapple", R.drawable.pineapple),
            Fruit("Strawberry", R.drawable.strawberry)
        )

adapter.data = fruitData

3. RecyclerViewにアダプターをセットする

FruitFragment
binding.itemList.adapter = adapter

コード

FruitFragment
class FruitFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        val binding: FragmentFruitBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_fruit, container, false)

        val adapter = FruitAdapter()

        val fruitData = arrayListOf(
            Fruit("Apple", R.drawable.apple),
            Fruit("Banana", R.drawable.banana),
            Fruit("Cherry", R.drawable.cherry),
            Fruit("Grape", R.drawable.grape),
            Fruit("Orange", R.drawable.orange),
            Fruit("Peach", R.drawable.peach),
            Fruit("Pineapple", R.drawable.pineapple),
            Fruit("Strawberry", R.drawable.strawberry)
        )

        adapter.data = fruitData

        binding.itemList.adapter = adapter

        return binding.root
    }
}

今回はRecyclerViewの使い方がメインのため、データバインディングの説明は省いています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0