Androidらしさを学ぶ (Material Design)

# はじめに
普段iPhoneを使っているAndroidエンジニア(1.5年程度)がAndroidらしさを学びたくマテリアルデザインの基礎の基礎を学んだものです

同じようにAndroidらしさの触り部分を学びたい方はご参照ください

モバイル向けのデザインの基礎にある[アクセシビリティ](https://developer.android.com/design/ui/mobile/guides/foundations/accessibility)、[システムバー](https://developer.android.com/design/ui/mobile/guides/foundations/system-bars)、[用語集](https://developer.android.com/design/ui/mobile/guides/foundations/glossary)について記載しています


# 基礎
## アクセシビリティ

世界人口の<INS>約6人に1人が障害のうちに重度または一時的な障害を経験</INS>する中で、使いやすく高品質なアプリであることで<INS>ユーザーと開発者両方が恩恵</INS>を得られる

#### 視覚アクセシビリティのガイドライン

まず、色のコントラストの<INS>ダメなデザイン例</INS>は以下

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/59c2bd36-9a08-122d-ab3f-7a9833579983.png"width=600>

アプリのコンテンツが可能な限り読みやすく、コンポーネントも視覚的に理解しやすくするための設計として以下のガイドラインに従う必要がある

- 様々なデバイスに対応できるよう、<INS>フォントサイズにはスケーラブルピクセル(sp)</INS>を使う
- bodyのフォントを<INS>12spより小さくしない</INS>
- 背景とテキストのコントラスト比は<INS>4.5:1</INS>になるようにする
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/c8e04c43-3019-493f-fd04-26f7919e07cd.png" width=300>
- 背景とボタンなどの非テキスト要素の間にはコントラスト比<INS>3:1</INS>を満たすようにする
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/0aa09c5a-748d-7bf2-02b4-7dd736d76520.png" width=600>
- リンクなどのアクションには複数のビジュアルアフォーダンスを使う



#### サウンドのガイドライン
[TalkBack](https://support.google.com/accessibility/android/answer/6283677)というGoogleスクリーンリーダーを用いて<INS>ユーザーが目を使わずにコントロール</INS>できる機能がある
アプリがスクリーンリーダーに対応できるとように以下のガイドラインがある
- コード内にUI情報を記述する
    - xmlは[contentDescription](https://developer.android.com/guide/topics/ui/accessibility/apps#describe-ui-element)
    - Composeは[Semantics properties](https://developer.android.com/jetpack/compose/semantics#properties)
- アイコンと画像の追加のテキスト説明を提供する
- 装飾アイテムの説明には null を設定
- アクションとコンテンツのブロック間をスキップできるようにするには、UI の細分性と UI 要素のグループ化を考慮する

#### オーディオ向けのデザイン
Androidは、ユーザーの様々な音声コマンドやクエリを通じてデバイスを操作できる

[Voice Access](https://support.google.com/accessibility/android/answer/6151848)を使うと、<INS>音声を使用してハンズフリーでアプリを開いたり、ナビゲートしたり、テキストを編集</INS>することができる

#### 運動能力に合わせたデザイン
[スイッチアクセス](https://support.google.com/accessibility/android/answer/6122836)を使用すると、ユーザーは<INS>別のデバイス</INS>を使用してAndroid端末を操作することができる

(操作用のデバイスのイメージ)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/60a0d7a4-cf85-19a5-6350-442814b7bc73.png" width=500>

<INS>タッチスクリーンを操作するのが難しい</INS>、手先の器用さが制限されているユーザに対して役に立つ機能

以下のガイドラインがある
- 全てのアクションを完了するために、<INS>ジェスチャ(スワイプなど)に依存しない形</INS>にする
    - (例：ゴミ箱アイコンで削除可能)<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/08e07f32-0720-ba8a-f0ab-b0f07f1899ff.png">
- UI要素のビジュアルを超えている場合でも、<INS>タッチターゲットが少なくとも48dp</INS>ある
- <INS>[触覚フィードバック](https://developer.android.com/develop/ui/views/haptics/haptics-principles)</INS>の利用を検討する


## Androidシステムバー
ステータスバーとナビゲーションバーを合わせて<INS>システムバー</INS>と呼ぶ

UI設計にかかわらずシステムバーが目立ってしまうことを考慮するのが重要
システムバーが確実に考慮されるよう、ほとんどのレイヤーの最上部に配置する

#### システムバーにおける重要な点
- <INS>UIセーフゾーン</INS>、<INS>システムインタラクション</INS>、<INS>入力方法</INS>、...などを考慮してデザインにシステムバーを含める
- 推奨事項：<INS>システムバーを透明</INS>にしてアプリを全画面でレイアウトし、バーの下にUIを継続して<INS>[edge-to-edge](https://developer.android.com/develop/ui/views/layout/edge-to-edge)を提供</INS>する
- 両方のバーを透明に設定できない場合は、<INS>バーの色をアプリ本体の色と一致</INS>させる
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/1d691067-c6b1-5377-a11f-1380c47fd983.png" width=600>
- edge-to-edgeやジェスチャーナビゲーションと<INS>競合する場所にタップジェスチャを追加しない</INS>
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/819845e5-710a-3fbc-7006-06176b6a4f7c.png" width=300>

#### システムバーの背後にコンテンツを描画するようにする
ユーザに没入型のエクスペリエンスを提供するため、ナビゲーションバーを透明にするなど<INS>edge-to-edgeを推奨している</INS>

edge-to-edgeの設計の際に次の**インセット**(画面のどの部分がシステムUIと交差するか)に注意する
- **システムバーインセット**は、タップ可能であり、システムバーによって視覚的に隠れてはいけないUIに適用される
- **システムジェスチャインセット**は、アプリよりも優先され、システムによって使用されるジェスチャナビゲーション領域に適用される

#### ステータスバー
Androidではステータスバーに<INS>通知アイコンとシステムアイコン</INS>がある
ユーザーはステータスバーを引き下げることで通知シェードにアクセスする
- ステータスバー領域
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/21729a4e-e73a-afdb-7eda-ae68b6c2558a.png" width=500>

ステータスバーは、時刻やユーザーが設定した<INS>パラメータやテーマによって表示が変わる</INS>
そして、スタイルを設定することもできる

- ライトテーマとダークテーマ
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/d12d7b22-e10b-e88f-6c9e-3e9afad81448.png" width=600>
- デフォルト(黒)
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/0129e3a0-1888-fe7d-ba18-73d2919fe180.png" width=600>
- スタイル付きバー
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/6f21250a-1361-2a46-25d0-df3e44e87401.png" width=600>
- edge-to-edgeを使用した透明バー
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/4e2c9a9a-046c-9fba-da39-d781cfe4e4ab.png" width=600>



システムバーをデフォルトの属性に設定したままにせず、コンテンツを強化したりアプリのブランドに合わせることが必要
- <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/7b76bc80-b348-0b3e-2268-6968faf4754a.png" width=600>

以下のようにステータスバーのスタイルを設定できる
```.xml
<style name="Theme.MyApp">
  <item name="android:statusBarColor">
    @android:color/transparent
  </item>
</style>
```

ディスプレイのカットアウトは、前面にあるセンサー用の領域でステータスバーの外観に影響を与える可能性がある
- [xml上で設定](https://developer.android.com/develop/ui/views/layout/display-cutout)することができる
- <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/ba881813-8df1-412c-3678-795a34aeeeb1.png" width=600>

#### ナビゲーションバー
Androidではユーザーが「戻る」、「ホーム」、「Overview」をコントロールして制御できる
- 「戻る」は前のビューに直接戻る
- 「ホーム」はアプリからデバイスのホーム画面に遷移する
- 「Overview」は最近開いたアプリが表示される
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/e6502306-ef0d-7161-1628-32dd25b9bf91.png" width=600>

ユーザーはジェスチャーナビゲーション(推奨)や3ボタンナビゲーションなど様々な構成を選択できる

##### ジェスチャーナビゲーション
ジェスチャーナビゲーションでは、「戻る」、「ホーム」、「Overview」の<INS>ボタンを使用する代わりにスワイプ</INS>での操作になる

良いUXを実現するためにジェスチャーナビゲーションでは以下のことを考慮する
- edge-to-edgeをサポートする
- ジェスチャーナビゲーションの下に押下可能なものを追加しない

参考：[ジェスチャーナビゲーションの実装](https://developer.android.com/develop/ui/views/touch-and-input/gestures/gesturenav)

#### イマーシブモード

イマーシブモード：全画面表示が必要な場合に<INS>システムバーを非表示</INS>にするモード

[デザイン例](https://developer.android.com/design/ui/mobile/guides/layout-and-content/immersive-content)：
- ゲームアプリ
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/443824f5-e7f4-825b-b57e-1ea5eca1214b.png" width=500>
- ビデオ通話
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/8a6be8d1-8507-ab98-7936-b804a5a23ee4.png" width=500>
- プレゼンテーション
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2044482/de109119-86da-4cba-b137-3c8a41618707.png" width=500>

[システムバーの表示切り替え](https://developer.android.com/develop/ui/views/layout/immersive)：
- 非表示　[WindowInsetsControllerCompat.hide()](https://developer.android.com/reference/androidx/core/view/WindowInsetsControllerCompat#hide(int))
- 表示　[WindowInsetsControllerCompat.show()](https://developer.android.com/reference/androidx/core/view/WindowInsetsControllerCompat#show(int))

このほかにも非表示にする際の振る舞いなどを指定できる

## 用語集
AndroidとUI関連の用語

|用語|説明|
|:--|:--|
|CTA(Call To Action)|ユーザーに実施してもらいたい行動の喚起<br>例：資料請求が目的のアプリで、「今すぐ資料請求をする」ボタンを画面上部に設置して資料請求を促す|
|Canonical layout|一般的なユースケースや画面サイズに適応させるために用いられるデザイン構成<br>例：[MateriaDesignのCanonical layout](https://m3.material.io/foundations/layout/canonical-layouts/overview)|
|Chroma(彩度)|グレー 〜 鮮やかな色のカラフルさの度合い|
|Containment|視覚的なグループ化の概念<br>例：[ダイアログ](https://m3.material.io/components/dialogs/overview)、[カード](https://m3.material.io/components/cards/overview)、[リスト](https://m3.material.io/components/lists/overview)|
|Density-independent pixels (dp)|どの画面でも均一な寸法になるように拡大縮小できる柔軟な単位<br>160dpi画面を基準にしていて1dpは1ピクセルとほぼ等しい|
|Display cutout|一部のデバイス上で、前面センサー用のスペースを提供するためにディスプレイ表面に広がる領域<br>わかりやすい：https://qiita.com/YusukeIwaki/items/c9ce1ecc9b6518112241|
|Hue(色相)|色の説明方法|
|Navigation bar|画面の下部に表示される Android システム バー|
|Scalable pixels (sp)|dpと同じ機能を果たすが、フォントに対してのみ機能する|
|Status bar|画面上部に表示される Android システム バー|
|Tasks|ユーザーが目標を達成するために従う一連のアクティビティ|
|Tone|色の輝度、または明るさ|

# おわりに
マテリアルデザインを学ぶための基礎を学びました

個人的には何も考えなければ突拍子もないデザインになりかねないと思うので、(トレードオフはありますが)ガイドラインに則っていくことで自分なりのこだわりを見つけていきたいです