MaterialDesign3で端末の壁紙から作られたテーマカラーが決められるって!?!?!??!?

# Material Design ってなぁに？

2014年にGoogleが提唱したデザインで、明確なガイドラインが定められています。
`Material Components`というライブラリが公開されているのでお手軽に使えるのが良いところですね。
しかも、Androidだけでなく、iOSやWeb向けのライブラリもあります。
2021年から[MaterialDesign3](https://m3.material.io/)が出てきました。

# 本題

## 壁紙からテーマカラーが決められるってどういうこと?

Android12のデザインコンセプトがMaterialDesign3となっています。
その中で色について、個人の色の好みやニーズを反映させようみたいなことが書かれているみたいです。
そのためAndroid12からはDynamic Colorというものが追加されました。

ホームを長押しして出てくる`壁紙とスタイル`で抽出された色が選択できます。
ここで選択された色が使用できるようになりました。

![Screenshot_20211215-203031.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193857/1b44ddde-4c51-59e4-cf3c-2ab66f2bc24e.png)

## 実際テーマカラーってどうやって使うの？

### 1 用意されているテーマを使う

これはとてもシンプルでAndroidManifestで指定しているThemeをMaterialDesign3のものを指定することで反映されます。
以下ではLightテーマを指定。

```xml:AndroidManifest.xml
<application
        android:name=".MyApplication"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        <!-- ↓でThemeを指定 -->
        android:theme="@style/Theme.Material3.Light">
```

```kotlin:MyApplication.kt
class MyApplication: Application() {
    override fun onCreate() {
        super.onCreate()
        // ↓を追加することでテーマがリアルタイムで反映される
        DynamicColors.applyToActivitiesIfAvailable(this)
    }
}
```

![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193857/5eb0f925-c4e3-9b7f-0b4f-d5a9baf61fa8.gif)


### 2 テーマの色を細かく指定したいor使いたい

動的なテーマカラーは以下のように定義されています。
注意点として、これはAndroid12以上でしか使用できませんので、バージョンで分けるなりしてください。
後ろに数字をつけることで`system_accent1_100`のように色調の指定ができます。
これで指定された色は`applyToActivitiesIfAvailable`をしなくても動的に反映されます。

| 名前 | どんな色か |
|:-|:-|
| system_accent1 | Primary Key Color <br> 目立つButtonやアクティブなものに向けた色 |
| system_accent2 | Secondary Key Color <br> フィルターの選択などのあまり目立たない部分に向けた色。 |
| system_accent3 | Tertiary Key Color <br> アクセントとして目立たせるために使用される色。 |
| system_neutral1 | Neutral Key Color <br> 背景などに向けた色 |
| system_neutral2 | Neutral Variant Key Color <br> 強調テキストやアウトラインに向けた色 |

MaterialDesign3のテーマで定義された色に関する属性はとても複雑で、`colorOnPrimary`のように定義されています。
マテリアルデザインでどんな色指定がされているかの確認は[MaterialDesign3](https://m3.material.io/)にあるComponentsから確認できます。

テーマを継承していくつか上書きしたものが以下になります。

```xml:theme.xml　
<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="DynamicColorsSample" parent="Theme.Material3.Light">
        <!-- Primary color -->
        <item name="colorPrimary">@android:color/system_accent1_300</item>
        <item name="colorOnPrimary">@color/white</item>
        <item name="colorPrimaryContainer">@android:color/system_accent1_500</item>
        <item name="colorOnPrimaryContainer">@android:color/system_accent1_500</item>
        <item name="colorPrimaryVariant">@android:color/system_accent1_300</item>
        <!-- Secondary color -->
        <item name="colorSecondary">@android:color/system_accent2_200</item>
        <item name="colorSecondaryVariant">@android:color/system_accent2_700</item>
        <item name="colorOnSecondary">@color/black</item>
        
        <item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
    </style>
</resources>
```
#### 反映前
![Screenshot_20211215-211106.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193857/1285c30d-e531-6fb5-87b8-fa6e66bf3018.png)

#### 反映後
![Screenshot_20211215-211203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193857/c9c2f387-fa77-a100-7918-7abfb0d4962f.png)


# まとめ
1.色の抽出はAndroidのシステム側で行い、候補の色をユーザーが選択するだけです。
2.どのパーツにどんな属性で定義されているかは[MaterialDesign3](https://m3.material.io/)で調べましょう。
3.思ったより簡単に使用できる。