3分で分かる？Android OのAdaptive Iconに対応しよう

DevFest Tokyo 2017の3分LTのネタです。 
https://gdg-tokyo.connpass.com/event/66236/
(もうちょっとちゃんとしたのをどこかで書くかもです。)

---

# Adaptive Iconに至るまで
なぜ出てきたか？

* Android 2.xの時代  
形がバラバラなアイコンで並んでいた時代がありました。  
丸や四角、様々な形のをしたアイコンが並んでいました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/27388/9e395390-d455-62ab-e2e2-59767ad63e43.png" width="200" />

(このためだけにエミュレーター入れました。。)


---

* Android 4.xの時代  
見た目がバラバラなのは見た目が良くないということで、
サードパーティやメーカーのランチャーアプリがアイコンを切り抜いて表示したり、アイコンパックの配布を始めます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/27388/c0d01226-ff5d-5479-8430-b24c75fdb137.png" width="400" />

https://play.google.com/store/apps/details?id=com.sec.android.app.launcher
より

---

* Android 7.1  
Round Iconが指定できるようになりました。ただ、丸だけというのは柔軟でないです。また丸く切り取られるだけで別に背景に透明を指定すればどんな形でも大丈夫でした。

```xml
<application
    android:icon="@mipmap/ic_launcher"
    android:roundIcon=“@mipmap/ic_launcher_round”
```

---

* Android 8.0  
Adaptive Iconが登場！制約を加えることで、柔軟に形が変えられるようになりました。

---

# Adaptive Iconとは？
アイコンは2層で構成されます。
それを切り取られてアイコンが作られます。
これによりアイコンの形を一貫したものにすることができます。
<img src="https://developer.android.com/guide/practices/ui_guidelines/images/NB_Icon_Layers_3D_03_ext.gif" width="400"/>
https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive.html より

---

二層で構成されるため、さまざまなアニメーションが可能になります。

<img src="https://developer.android.com/guide/practices/ui_guidelines/images/Single_Icon_Parallax_Demo_01_2x_ext.gif" width="400" />
https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive.html より

---

# 対応するには？
対応ポイント

* 基本的な所を抑える
* 簡単に対応するか？ちゃんと対応するか？
* サイズをどう抑えるか？

---

## 基本的な所を抑える1
108dp x 108dpで前面、背面の画像を作成する。
中心から直径66dpにアイコンのコアな部分を表示する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/27388/fca5b171-9374-93b6-be85-9e752eff1a2d.png)
https://www.youtube.com/watch?v=TB-K6OniF68 より

それ以外は切り取られる可能性がある。
基本は今までのpng画像(48dp) + Adaptive Icon用の前面の画像、 背面の画像(108dp)を各解像度用に用意する形になります。

---

## 基本的な所を抑える2
API Level 26用にic_launcherを用意して、それ以外はmipmap-[]dpi/ic_launcher.pngを使うようにする。

```xml:/res/mipmap-anydpi-v26/ic_launcher.xml
<adaptive-icon ...>
  <background android:drawable="@mipmap/ic_background" />
  <foreground android:drawable="@mipmap/ic_foreground" />
</adaptive-icon>
```

---

## 簡単に対応する

* 一番ベーシックなパターン  
簡単に対応するにはただ単に背景色 + ブランドアイコンを載せるのみ  
1時間で対応が終わるはずです。

---

## Adaptive Iconの制約を利用して対応する

* クリエイティブなカスタマイズが色々出来る  
前面にあると思わせて、背景に要素をおいておくことで、うまくアニメーションができます。

Googleの方のブログと共に以下のパターンが有るというのはデザイナーさんに伝えて一緒に考えるのが良さそうです。
https://medium.com/google-design/designing-adaptive-icons-515af294c783

---

* Background Anchoring
* Masked masks
* Light & shadows
* Leave behinds

Masked masksの例(ロゴが前面にあると思わせて背面にあることで面白い効果が起こる)
![](https://qiita-image-store.s3.amazonaws.com/0/27388/56c944ab-c4c4-87a4-9916-d08620126d72.gif)
https://medium.com/google-design/designing-adaptive-icons-515af294c783 より

---

デザイナーさんは[このツール](https://adapticon.mariusclaret.com/)にpng画像をいれることでAdaptive Iconを確認しながら進めることができます
![test.gif](https://qiita-image-store.s3.amazonaws.com/0/27388/6817242a-7009-2b5d-83cc-7f8379966f5f.gif)




---

またエンジニアはここからダウンロードできるapkでアプリとして動作を確認できます。
https://github.com/nickbutcher/AdaptiveIconPlayground/releases

![adaptive-icon-playground-demo.gif](https://qiita-image-store.s3.amazonaws.com/0/27388/0a90a04b-2f87-191b-1483-352078cc043b.gif)


---

## apkサイズをどう抑えるか？

* 普通のアイコン
* Round Icon
* Adaptive Icon

に対応して、mdpiからxxxhdpiを用意すると5 x 4 = 20個の画像をアイコンのために入れる必要があります。
さらにApp Shortcutも含めるとさらに増加します。

Android Studio 3.0 Beta7のデフォルトの画像構成

<img src=https://qiita-image-store.s3.amazonaws.com/0/27388/73b1b3bb-9528-4353-fe6b-c2a548aa5ce3.png width="200" />


---

### 可能であればVectorDrawableを利用する。
利用することができれば解像度ごとにpng画像を用意しなくていいので、サイズの節約になります。
Android Studio 3.0 Beta7のデフォルトの画像構成でもAdaptive Iconの背景にVectorDrawableを利用しています。

<img src="https://qiita-image-store.s3.amazonaws.com/0/27388/bed3b868-75e8-ddb1-0606-210683f45b26.png" width="300" />

<img src="https://qiita-image-store.s3.amazonaws.com/0/27388/25a89c91-e38c-b21c-0798-ab83503f69a5.png" width="300" />


---

### 背景が単色であれば単色を利用する

画像を使わないことでサイズを削減できます。

```xml:/res/mipmap-anydpi-v26/ic_launcher.xml
<adaptive-icon ...>
  <background android:drawable="@color/light_grey" />
  <foreground android:drawable="@mipmap/ic_foreground" />
</adaptive-icon>
```

---

### App Shortcut(API Level 25)でVectorDrawableを使う
`AdaptiveIconDrawable`でinsetタグを利用すればAPI Level 25と26で共通の一つのVectorDrawableで対応できます。(通常なアイコンはAPI Levelが古いのでVectorDrawable化できないが、App Shortcutはできる)

```xml:/res/mipmap-anydpi-v26/shortcut.xml
<adaptive-icon ...>
  <background android:drawable="@color/light_grey" />
  <foreground>
    <inset
      android:drawable="@drawable/ic_shortcut_search_foreground"
      android:inset="9.26%" />
  </foreground>
</adaptive-icon>
```

---


### Round Iconのv26以降向けのAdaptive IconはランチャーアイコンのAdaptive Iconと同じリソースを使う
Round IconのAdaptive Iconの対応として以下で対応できます。
※これをしても、API Level 25向けに 結局ic_launcher_round.pngが必要です

```xml
<application
    android:icon="@mipmap/ic_launcher"
    android:roundIcon=“@mipmap/ic_launcher_round”
```

```xml:/res/mipmap-anydpi-v26/ic_launcher_round.xml
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@drawable/ic_launcher_background" />
    <foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>
```

---

### アイコンを丸くしてしまう
pngの画像がアイコンが丸く切り取られることが許容できない場合はAndroid 7.1用にRound Iconを用意する必要があります。
これに対して、自分だとこの発想が出てこなかったのですが、根本のアイコンごと丸くしてしまう方法があります。
そうすればroundIconも普通のIconもAdaptiveIconも基本的に同じデザインを適応することができます。

```xml:AndroidManifest.xml
<application
    android:icon="@mipmap/ic_launcher"
    android:roundIcon="@mipmap/ic_launcher"
```

---

# ハマリポイント
* 現在launcher iconにxmlを指定するとlintでエラーが出るので、エラーが出たらSuppressしておくと良さそう( http://crbug.com/739746 情報が少ない。。)

こちらAndroid Gradle Plugin 3.0では起きないっぽいです。

---

# まとめ
まずはデザイナーさんにAdaptive Iconをシェアして興味あるか聞いてみよう(自分の場合はデザイナーさんから言っていただけました。 :bow: )
APKサイズを小さくするテクニックは色々あるので、それを使っていこう。


---

# 参考資料

https://www.youtube.com/watch?v=TB-K6OniF68
https://medium.com/google-design/understanding-android-adaptive-icons-cee8a9de93e2
https://medium.com/google-design/designing-adaptive-icons-515af294c783
https://medium.com/google-developers/implementing-adaptive-icons-1e4d1795470e