Android8.0 (Oreo API-level v26)よりAdaptive Iconへの対応が追加されました。
Adaptive Iconを使用することで全面画像と背景画像を分けて定義して、ユーザーのアクションに応じたアニメーションなどに対応できます。
Adaptive Iconについて詳しくはこちら
https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive
#真面目に対応するなら
本格的な対応をするなら次のような対応が必要になります。
##前面画像の用意
前面画像は108dp × 108dp。従来のアイコンは48dp × 48dpなので互換はない。
##背景画像の用意
同じく背景画像は108dp × 108dp。やはり互換はない。
それぞれ各DPIごとに用意するか、Vectorで用意する必要がある。
めんどい
デザイナーがすでに抜けていたりするので追加の画像は自分でどうにか用意しないといけなかったり、すでにldpi,mdpi,hdpi,xdpi,xxdpi,xxxdpiと6サイズもアイコンが内包されているのに、さらに各DPIごとに画像を用意するのは今後の保守面でも辛い。
#追加の画像を使わずにAdaptive iconに対応させる
ということで、画像ファイルを追加することなく、従来のアイコンを使ってadaptive iconに対応させてみます。
##背景画像の用意。
実はAndroid7.0以降ではランチャーアイコンに従来のPngだけでなくVectorなどのXMLなどが使用できます。
ベタ塗りの背景画像でよければ単に以下のように準備するだけです。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffff" />
</shape>
前面画像の用意。
前面画像は既存のアイコンを流用します。
しかし、前述のようにAdaptive Iconではサイズが108dpとなっていてそのままでは互換がありません。
Photoshopなどで余白を付けた画像を用意するのも良いですが、ファイルサイズが大きくなるし、今後アイコンを変えたいときとかに余計な手間が増えてしまいます。
そこで、ここでもXMLを使用して従来のアイコンの周りに余白を付けて108dpの画像ファイルにします。
余白を付けるにはinset タグを使用します。従来48dpの画像の上下左右に30dpの余白を付けることで108dpの画像ができあがります。
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:inset="30dp">
<bitmap android:src="@mipmap/ic_launcher" />
</inset>
Adaptive iconの用意。
Adaptive Iconは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="@drawable/ic_launcher_foreground" />
</adaptive-icon>
注意点:通常のチュートリアルではこのファイル名をic_launcher.xmlとすることで、@mipmap/ic_launcherがv26未満ではpngを見に行き、v26以降ではxmlを見に行くようにすることでバージョンごとにアイコンを切り分けています
。しかし今回はic_launcher_foreground.xml内でic_launcher.pngを参照しに行く必要があるためこの方法が使用できません。
そのため従来の画像はic_launcher、Adaptive Iconはic_laucher_adaptiveと名前を分けています。
##バージョンによる切り分け。
上記のように通常であれば同じmipmap/ic_launcherという名前にすることでバージョンによってアイコンを切り分けることができるのですが、今回は新しいバージョンで旧バージョンのアイコン画像を参照する必要があるのでこの方法が使えません。
そこでApp resources overviewの仕組みを使ってバージョンによりic_launcherとic_launcher_adaptiveに切り分けます。
valuesフォルダの中に mipmaps.xmlを作成し
@mipmap/ic_launcherに対してiconという別名を付けます。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<drawable name="icon">@mipmap/ic_launcher</drawable>
</resources>
次にv26以上で処理を上書きするために
Values-v26フォルダを作成し、mipmasp.xmlを作成し@mipmap/ic_launcher_adaptive.xmlに対してiconという別名を付けます。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<drawable name="icon">@mipmap/ic_launcher_adaptive</drawable>
</resources>
最後にAndroidManifest.xmlを修正してアイコンをdrawable/iconに変更します
…
<application
…
android:icon="@drawable/icon"
…
現状ですが、AndroidStudio 3.2 Canary15でいくつかの警告が出るようです。
一つはmitmaps.xml内でに対して the drawable "icon" in values... のようなエラーが出ます。
別名をつけているだけなのでiconはdrawableの中にいなくていいと思うのですが・・・
もう一つはAndroidManifest.xmlの中でCannot resolve symbole @drawable/iconが発生します。
drawableの中に指定しているので参照できるはずなのですが、本来トリッキーな方法なので、この辺詳細を知っている人がいたら教えてもらえると嬉しいです。