February 22, 2020

UXを上げるため、リストのタッチ範囲をDatabindingでシュッと書く

Androidの小ネタです。 リストにチェックボックスなどがあるこのようなUIの場合、 普通に実装するとタッチ範囲がチェックボックスのみになってしまうため、タッチ範囲が狭くあまり良いUXとは言えません。

list example

何も考えずに書くとこうなると思います。

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

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingStart="16dp"
        android:paddingTop="8dp"
        android:paddingEnd="16dp"
        android:paddingBottom="8dp"
        >

        <TextView
            android:id="@+id/title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:gravity="start"
            android:lines="1"
            android:text="Title"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@id/checkbox"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />

        <com.google.android.material.checkbox.MaterialCheckBox
            android:id="@+id/checkbox"
            android:layout_width="36dp"
            android:layout_height="36dp"
            android:layout_marginStart="8dp"
            android:gravity="center"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

このままだとタッチエリアはチェックボックスのみになります。

list touch area only checkbox

コード側でClickListener使ってやるのも なんだかな~ という気持ちになります。

class HogeAdapter(
) : RecyclerView.Adapter<HogeViewHolder>() {

    ...

    override fun onBindViewHolder(holder: HogeViewHolder, position: Int) {
        holder.itemView.setOnClickListener {
            checkbox.isChecked = !checkbox.isChecked
        }
    }
}

今回はxml側で解決したいので、data bindingを使って performClickを呼び出してあげます。
data bindingを使うとこうなります。

android:onClick="@{() -> checkbox.performClick()}"
<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/rootLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:foreground="?attr/selectableItemBackground"
        android:onClick="@{() -> checkbox.performClick()}"
        android:paddingStart="16dp"
        android:paddingTop="8dp"
        android:paddingEnd="16dp"
        android:paddingBottom="8dp"
        >

        <TextView
            android:id="@+id/title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:gravity="start"
            android:lines="1"
            android:text="Title"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@id/checkbox"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />

        <com.google.android.material.checkbox.MaterialCheckBox
            android:id="@+id/checkbox"
            android:layout_width="36dp"
            android:layout_height="36dp"
            android:layout_marginStart="8dp"
            android:gravity="center"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

これだけで、リスト全体にクリック範囲をつけてチェックボックスを操作出来るようになりました。
個人的にこういうUXを意識した使いやすいアプリが増えると嬉しいです。

list touch area is all area

© AAkira 2019