【Kotlin×Android】リストビューのレイアウトカスタマイズ
リストビューはデフォルトのままだとテキストしか表示できませんが、
自分でレイアウトを作りそれを使用するでテキスト以外の情報も表示させることができるようになります。
今回はリストビューのレイアウトをカスタマイズする方法を紹介します。
以下のような画面を作成します。

必要なもの
カスタマイズするために必要なものは以下お通りです。
- BaseAdapterを継承したアダプタークラス
- リストに表示させる情報を定義したdataクラス
- リストのアイテムとして表示させるlayoutファイル
BaseAdapterを継承したアダプタークラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package com.example.listviewcustom import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.BaseAdapter import android.widget.TextView class CustomListAdapter(private val context: Context, private val data: List<ListItem>, private val resource: Int): BaseAdapter() { private val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater override fun getCount(): Int { return data.size } override fun getItem(p0: Int): ListItem { return data[p0] } override fun getItemId(p0: Int): Long { return data[p0].id } override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View { val item = getItem(p0) val view = p1 ?: inflater.inflate(resource, null) view.findViewById<TextView>(R.id.text_title).text = item.title view.findViewById<TextView>(R.id.text_id).text = item.id.toString() return view } } |
1 2 3 |
CustomListAdapter(private val context: Context, private val data: List<ListItem>, private val resource: Int) |
コンストラクターで各種必要な情報を受け取ります。
- context
- コンテキスト
- data
- 表示させるデータ
- resource
- レイアウトファイル
1 |
private val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater |
レイアウトファイルをViewのオブジェクトに変換するためにLayoutInflaterを取得します。
後で出てきますが、このオブジェクトのiflateメソッドを使用します
1 2 3 4 5 6 7 8 9 10 11 |
override fun getCount(): Int { return data.size } override fun getItem(p0: Int): ListItem { return data[p0] } override fun getItemId(p0: Int): Long { return data[p0].id } |
この部分は何をするものなのか何となくイメージできると思います。
データの個数、アイテム、アイテムのIDをそれぞれ取得します。
1 2 3 4 5 6 7 |
override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View { val item = getItem(p0) val view = p1 ?: inflater.inflate(resource, null) view.findViewById<TextView>(R.id.text_title).text = item.title view.findViewById<TextView>(R.id.text_id).text = item.id.toString() return view } |
この部分でviewに値を設定しています。
inflateメソッドでレイアウトファイルをViewに変換しています。
ただレイアウトファイルの解析は時間がかかるため再利用できるものがある場合はそれを使用します。
リストに表示させる情報を定義したdataクラス
1 2 3 4 5 6 7 |
package com.example.listviewcustom data class ListItem( val id: Long, val title: String, ) |
リストのアイテムとして表示させたい情報を定義します。
今回はidとtitleを定義しました。
リストのアイテムとして表示させるlayoutファイル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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"> <TextView android:id="@+id/text_title" android:layout_width="413dp" android:layout_height="60dp" android:text="title" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/text_id" /> <TextView android:id="@+id/text_id" android:layout_width="107dp" android:layout_height="46dp" android:layout_marginTop="4dp" android:layout_marginEnd="304dp" android:text="id" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/imageView2" android:layout_width="52dp" android:layout_height="48dp" android:layout_marginTop="2dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@android:drawable/ic_input_get" /> </androidx.constraintlayout.widget.ConstraintLayout> |
idを表示させるためのTextView、
titleを表示させるためのTextView、
画像を表示させるためのImageViewを配置しています。
MainActivity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package com.example.listviewcustom import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import android.widget.ListView class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val listView = findViewById<ListView>(R.id.listView) val data = listOf( ListItem(1, "メモタイトル1"), ListItem(2, "メモタイトル2"), ListItem(3, "メモタイトル3"), ) listView.adapter = CustomListAdapter(this, data,R.layout.list_item) } } |
ここまでくればやることは簡単で先ほど定義したdataクラスであるListItemの配列を作成し、CustomListAdapterに渡します。
さらにそれをListViewのadapterに設定すれば完了です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/coordinatorLayout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <ListView android:id="@+id/listView" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginTop="36dp" android:layout_marginEnd="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
MainActivityのレイアウトにはListViewのみを配置しています。