Androidの単一選択UI、こんな方法もあるかも？

「複数の選択肢から1つを選ばせたい」ということがよくあると思うのですが、皆さんならどんなUIを作るでしょうか？

私がパッと思いつくのは「ラジオボタン」でしたが、今回改めてどんな選択肢があるのか、身の回りのアプリをチェックしながら考えてみました。

## 目次
1. [Segmented buttons (Material Components)](#1segmented-buttons-material-components)
2. [Chips (Material Components)](#2chips-material-components)
3. [Radio button (Material Components)](#3radio-button-material-components)
4. [Drop-down menu (Material Components)](#4drop-down-menu-material-components)
5. [独自UI](#5独自ui)
6. [まとめ](#6まとめ)
7. [終わりに](#7終わりに)

## 1.Segmented buttons (Material Components)
![f6a5fde20f57-20240114.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145704/1d3f34ed-0223-1db9-07d4-55826c80367a.jpeg)

Google Mapなどで使われているこのUI「Segmented buttons」というコンポーネントのようです。

「以前toggle buttonをこんな形にカスタムしたことがあるような..？」と思ったらどうやらM2の時はtoggle buttonsだったもののようでした。
> [Name and types: Segmented buttons were previously known as toggle buttons. They now have two official types: single-select and multi-select.
](https://m3.material.io/components/segmented-buttons/overview#aee6edc3-c843-497a-8882-dfb4fdef1657)

ガイドラインなどを見ていくと、
```
・用途は「オプションの選択」「ビューの切り替え」「要素の並べ替え」など
・「複数選択」「単一選択」どちらにも使える
・2〜5個かつ、ラベルが短く済むシンプルな選択肢向け
```
などの特徴がありそうでした。

>ラベルが短く済む

については「ボタンに入りきらない場合はアイコンの単独使用を検討してね」といった記述もありました。
![スクリーンショット 2024-03-03 2.56.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145704/d52a2b7f-f799-7e17-91ea-a622bdd9edc2.png)

↑に「**ただし、意味がちゃんと伝わるか注意してね**」と書かれているように、アイコンだけで意味を伝えるのが難しく、長文での説明が必要な「アプリ独自のモードや設定」などはこのコンポーネントには向いていなそうですね。
逆に「色」「時間帯」のような**シンプルで一般的な概念には向いていそう**です。

ちなみにJetpack Composeの対応はまだ「Planned」らしいです.. 残念
![c32e0d5fd0cc-20240115.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145704/f6b9a37a-27b7-182e-acb2-9e8b5ea311f1.png)
https://m3.material.io/components/segmented-buttons/overview

## 2.Chips (Material Components)
![Screenshot_20240125-010850~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145704/6fb88632-3389-1ecc-e9c9-0ea5ac274a7f.jpeg)

「選択肢が5個以上ある場合こっちを使ってね」ということでSegmented buttonsのガイドラインで紹介されていました。
これは検索条件のフィルタなどのシーンで最近すごくよく見かける気がしますね。
手元のアプリでは旅行アプリの「Agoda」で予約照会結果をフィルタする際に使われていました。

これもSegmented buttons同様「単一選択でも使える」らしいです。
シンプルでスペースを取らないので、この画面のようにタブ選択など他のUIと共存させる時にもいいかもしれないですね。

ドキュメントを見た感じ、結構いろんな用途で使えるコンポーネントのようです（意識したことなかったけど「Action」とかは確かによくみる！となりました）
![スクリーンショット 2024-01-25 1.22.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145704/eb057232-fad9-be49-ea48-bf56830fc414.png)
https://m3.material.io/components/chips/guidelines

こちらはCompose対応もされており、たとえば、以下のようなフィルターチップは、
![スクリーンショット 2024-01-25 10.53.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145704/d87a317c-5590-ace2-5bc7-758c01cf06a2.png)

以下のようなコードで実装することができます。

Compose部分
```kotlin:
var selectedFruit: Fruit by remember {
    mutableStateOf(Fruit.Orange)
}

Row {
    Fruit.entries.forEach {
        FilterChip(
            modifier = Modifier.padding(8.dp),
            selected = it == selectedFruit,
            onClick = { selectedFruit = it },
            label = { Text(text = it.labelText) },
            leadingIcon = {
                if (it == selectedFruit) {
                    Icon(
                        imageVector = Icons.Default.Check,
                        contentDescription = null
                    )
                }
            }
        )
    }
}

```

選択肢となるリストなどの定義（今回はenumを使用）
```kotlin:Fruit.kt

enum class Fruit(val labelText: String) {
    Orange("orange"), Banana("banana"), Apple("apple")
}
```

FilterChipはまだExperimentalではありますが、かなりシンプルなコードで記述できるようになっていると思うので、ご興味のある方は見てみてください。
https://developer.android.com/jetpack/compose/components/chip?hl=ja

## 3.Radio button (Material Components)
![Screenshot_20240125-010640.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145704/d776c3a0-a655-0502-794c-4ad29b4a3b32.jpeg)

「複数の選択肢から1つを選ばせる」と聞いた時に一番最初に思いつくのがこのUIではないでしょうか。
バーガーキングアプリでの「お受け取り方法」の選択や、Android標準の設定アプリなどでも多く使われていました。

Radio buttonは、画面スペースに余裕がある場所向けのコンポーネントらしく、
「画面上のスペース節約が重要な場合はDropDownメニューを検討してね（ただし、クリック数的にも認知コスト的にもユーザにより大きな負担がかかるから気をつけてね）」
的なことが書かれていました。

![23efab9d5a51-20240115.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145704/0092b689-c1c6-662e-1e4c-c16fabd735dd.png)

https://m3.material.io/components/radio-button/guidelines

Segmented buttonsもChipsもかなり短めの文字列しか入らないので、
**スペースが広く使えてかつ、↓のように長めの文字列を入れたい場合**は引き続き重宝しそうですね
![Screenshot_20240125-010547 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145704/da33fa42-17dc-9f35-3476-6a2d97ebc3b0.jpeg)

## 4.drop-down menu (Material Components)
![daad1bcb3ec8-20240115.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145704/af3bc9eb-1f9e-9054-23d8-86a3b1abfd35.jpeg)
drop-down menuは健康管理アプリ「あすけん」のメール配信時間設定の画面に使われてました。
RadioButtonと似たようなユースケースで、より**スペースに制約がある場合**に使えそうです。
選択肢が多いと見づらさを感じますが、「配信時間」のようにソートされているデータだとそこまで認知コストをかけずに済みそうな気がしました。

https://m3.material.io/components/menus/overview
## 5.独自UI

![3376d6e65b26-20240114.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145704/88c4f99a-0ba5-ba1d-ea3d-c4340869d5b3.jpeg)

マクドナルドのアプリでは、ドリンクのサイズ選択に独自のUIが使用されていました。
標準コンポーネントを使うより多少手間がかかるかもしれませんが、このようなUIは**複数の情報（例えば、サイズと追加料金）を視覚的に表示する際**にとても有用だと思いました。


## 6.まとめ
ありきたりなまとめですが、選択肢の内容にマッチしたUIを選ぶのが大事だと思いました。

たぶん、GoogleMapでいう「★数」のようにシンプルかつ説明不要な選択肢をRadio buttonにすると無駄にスペースや認知コストを取るし、
逆にマクドナルドの飲み物のサイズ（M or L[+20円]）のように情報量が多めのものを無理やりSegmented buttonsに詰め込むと見づらかったりすると思うので。。。。。

また、MaterialDesignのガイドラインでは、
「Segmented buttons は2〜5個まででそれ以上はchipsを使う」
「drop-down menuは省スペースに時に有効だが、クリック数的にも認知コスト的にもユーザにより大きな負担がかかる」
など各UIコンポーネントに関する説明もされているので、特徴や注意点などをよく理解した上で上手に使い分けていきたいです。

## 7.終わりに
お読みいただいた方、ありがとうございました！記事に関する訂正、補足情報や、他にもおすすめのUIなどありましたらコメントで教えていただけると喜びます。

またこの記事のベースにしたZennのスクラップではここで割愛した例も載せているので、もっと色々な例がみたい方などはご参照ください
https://zenn.dev/stoo/scraps/5d0d5a840eb6f7