Sunday, March 8, 2020 / Android, Jetpack

Android Jetpack: RecyclerView を使った一番簡単なリストの改良:二列に表示

RecyclerView Two Columns

いまさらですが Jetpack によるUI構築編、その2。 前回 一番簡単なリストをつくりましたが、それを改良して、二列表示に変えます。

変更点(1)

app/src/main/res/layout/my_item_view.xml を修正。

TextView を2個に変更します。

変更前:

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

変更後:

<?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="wrap_content"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/my_left_item"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_weight="1"
        android:text="" />
    <TextView
        android:id="@+id/my_right_item"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_weight="1"
        android:text="" />

</LinearLayout>

TextView を1個から2個に増やし、 android:layout_weight="1" 属性を追加. ここでは両方とも weight を 1 にしているの 50% 50% でちょうど半分の大きさで分割されます。 片方だけ狭くする場合はこの weight 値を適当に調整しましょう。

変更点(2)

各アイテムに入れる内容を String から Pair<String, String> へ変更。 要するに一行につき2個のテキストが必要になったので、ここでは Pair を使っています。

たとえば、ユーザー名で firstName, lastName を入れたい場合などは、Pairの代わりに data class User(val firstName: String, val lastName: String) のようなデータクラスを使った方がよいかもしれません。

MyAdapter.kt の変更

一行につきテキストを左右に2つ設定するように変更。

変更前:

class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val textView = itemView.findViewById<TextView>(R.id.my_item)
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    holder.textView.text = dataset[position]
}

変更後:

class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val textViewLeft  = itemView.findViewById<TextView>(R.id.my_left_item)
    val textViewRight = itemView.findViewById<TextView>(R.id.my_right_item)
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    val pair = dataset[position]
    holder.textViewLeft.text  = pair.first
    holder.textViewRight.text = pair.second
}

MainActivity.kt の変更

データセットを List<String> から List<Pair<String, String>> に変更。

変更前:

private val dataset: List<String> by lazy {
    val list = mutableListOf<String>()
    0.until(100).forEach {
        list.add("- item ${it}") 
    }
    list
}

変更後:

private val dataset: List<Pair<String, String>> by lazy {
    val list = mutableListOf<Pair<String, String>>()
    0.until(100).forEach {
        list.add( Pair("left ${it}", "right ${it}") )
    }
    list
}

区切り線の追加

見た目の改良のため、アイテムとアイテムの間に区切り線を入れます。 これは RecyclerView に DividerItemDecoration を追加します。(1)

recyclerView.apply {
    layoutManager = viewManager
    adapter = viewAdapter

    // (1)
    addItemDecoration(
        DividerItemDecoration(
            recyclerView.context,
            DividerItemDecoration.VERTICAL
        )
    )
}

まとめ

割と簡単に二列に変更できました。