自作クラスを使ったListViewの使い方をまとめます。この記事を書いた時点で用いているサンプルプロジェクトは以下。
github.com
やること
ListVIewを使うための準備は3つです。
- ListViewに表示するレイアウトを作る
- Adapterクラスを作る(アイテムの内容はここで設定)
- アクティビティへの配置とAdapterのセット(アイテムをタップした時の処理はここで設定)
最終的に、以下の画像のようなレイアウトの列挙が出来ます。
表示するレイアウトを作る
レイアウトファイルを追加し、ListViewに表示するレイアウトを作ります。
この記事ではlanguage_item.xmlとしてTextViewを3つ水平に並べたものをサンプルとします。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <TextView android:id="@+id/num" android:layout_width="50sp" android:layout_height="match_parent" android:background="@color/colorPrimary" android:textSize="30sp" android:textColor="@color/colorWhite" android:gravity="center" android:shadowColor="@color/colorBlack" android:shadowRadius="10.0" android:text="99"/> <TextView android:id="@+id/language" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="5" android:textSize="30sp" android:text="language"/> <TextView android:id="@+id/parcent" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="3" android:textSize="30sp" android:gravity="right" android:text="nnn.nn%"/> </LinearLayout>
Adapterクラスを作る
Adapterクラスは表示するItem全てを管理します。処理の流れとしては「コンストラクタに表示したいデータを渡して初期化→getViewで表示するViewを初期化」となります。
サンプルとしたLanguageAdapter(下記)では、getView内でアイテムに対応する文章や色を設定しています。
class LanguageAdapter(val context: Context, val sortedList: List<Pair<String, Int>>, numOfReps: Int, val numColorIds: ArrayList<Int>) : BaseAdapter() { val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater var sumOfReps = numOfReps.toDouble() override fun getCount(): Int { return sortedList.count() } override fun getItem(position: Int): Pair<String, Int> { return sortedList[position] } override fun getItemId(position: Int): Long { return position.toLong() } @SuppressLint("ViewHolder", "SetTextI18n") override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { val view = layoutInflater.inflate(R.layout.language_item, parent, false) //表示するレイアウト取得 val numtext = view.findViewById<TextView>(R.id.num) numtext.text = "${sortedList[position].second}" numtext.background = ColorDrawable(ContextCompat.getColor(context, if(numColorIds[position] != 0) numColorIds[position] else R.color.colorWhite)) view.findViewById<TextView>(R.id.language).text = sortedList[position].first view.findViewById<TextView>(R.id.parcent).text = "${String.format("%3.2f", ((sortedList[position].second * 100).toDouble() / sumOfReps))}%" return view } }
アクティビティへの配置とAdapterのセット
ここまで作った内容を使うため、以下の3手順を行います。
- ListViewをレイアウトに配置
- ListViewにAdapterをセット
- ListViewにタップ時の挙動を設定
ListViewをレイアウトに配置
レイアウトに加えるだけです。
︙ <!-- リストビュー配置 --> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent"/> <!-- リストビュー配置 --> </LinearLayout>
ListViewにAdapterをセット
以下のように、listViewにアダプターを入れるだけです。
val listView = findViewById(R.id.listView) listView.adapter = LanguageAdapter(/* コンストラクタに必要な引数 */)
ListViewにタップ時の挙動を設定
setOnItemClickListenerでタップ時の挙動が設定できます。
positionにはタップされたアイテムの番号が入っており、例えばparent.getItemAtPosition(position)を呼び出すことでAdapterクラスに作成したgetItem(position: Int)を呼び出すことができます。
val listView = findViewById(R.id.listView) listView.setOnItemClickListener{parent, v, position, id -> /* タップ時の挙動 */ }
ここまでの操作で自作クラスを使ったListViewが使えます。