【Android】今日からできるSplashアイコンアニメーション【Splash】

この記事はand factory.inc Advent Calendar 2021 23日目の記事です。
昨日は[@doihei](https://qiita.com/doihei)さんの[GitHub Template Repository](https://qiita.com/doihei/items/223c273a1aef467fc3fd)使ってみたでした。

# はじめに

Android12が出てから、YoutubeやGoogle公式アプリ(MapやGmail)のSplashにアニメーションが追加されて、めちゃくちゃオシャレになったよね👀
ユーザーの目に入るのはアプリを開く一瞬だけだけど、ちょっと動きが追加されるだけでワクワク感が出ててとっても素敵。

是非とも真似したいと思って色々調べてきたので、Splashアイコンのアニメーション実装方法を紹介するよ。

## 完成形

Before | After
:--: | :--:
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474683/75ee5e0f-9392-6a58-7fb4-a2e761550c6f.gif" width="300" /> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474683/e39ef300-7a76-2595-60ba-fffdf9fec28e.gif" width="300" />

ミニマムな修正にしたかったので、今回はDroid君のalphaを変えるだけ。
違いは地味だけど、比較して見ればちゃんとアニメーションされてるのがわかるね。

## 実装手順

実装手順は下記の通り。

1. AnimatedVectorDrawableを用意する。
2. theme.xmlにSplashの設定を追加する。
3. AndroidManifestでthemeを設定する。

順に解説していくよ。

### 1. AnimatedVectorDrawableを用意する。

まずは、アニメーションさせるアイコンのリソースを追加するよ。
公式のドキュメントによると

> AnimationDrawable と AnimatedVectorDrawable でオブジェクトのアニメーション化と描画が可能な場合、開始ウィンドウを表示しつつアニメーションを再生することもできます。

らしいんだけど、AnimationDrawableを設定しても何故かアニメーションしてくれなかったので、僕はAnimatedVectorDrawableを作ったよ。
未だになんでできなかったかわかってないので、詳しい人教えて欲しい。

「は？？AnimationDrawableならまだしも、AnimatedVectorDrawableとか自前で用意するの大変じゃん！」と思ったんだけど、ありがたいことに[Shape Shifter](https://shapeshifter.design/)ってツールを使えば簡単に作れちゃった。

まずは画面左下にあるImportでアニメーション前のベクター画像かsvg画像をインポートする。

![スクリーンショット 2021-12-23 15.04.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474683/3d853391-dbf0-edfe-ecaf-61153cce9c08.png)

次に、追加した画像のpathの横にある⏰マークで、「時間経過で変更したい値」を選択するよ。
今回は時間経過とともにalphaを変更したいので、fillAlphaを選択する。

![スクリーンショット 2021-12-23 15.05.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474683/2c09abb7-8650-3c6a-40f9-1432529673df.png)

※GmailやGoogleMapみたいに時間経過で形も変わるような場合は、多分pathDataを選択するんだと思う。

すると画面右側で何秒間でどれくらい値を変えるのかを編集できるようになるので設定していく。

![スクリーンショット 2021-12-23 15.13.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474683/3ac829bd-8e51-31e7-89a1-be1741c2eea2.png)

Splashのアニメーションは最長で1,000msだから、endTimeは1000を設定。
fromValueとtoValueは読んで字の如く、元の値と変化後の値なので、元の値は透明の0、変化後の値はくっきり1に設定。

あとはこいつをexportして一旦リソース完成〜✨
作ったリソースはdrawable配下に置いてあげてね。

今回は必要なことしかやってないけど、慣れればもっといろんなことができそうね。

### 2. theme.xmlにSplashの設定を追加する。

作ったリソースを設定するには、theme.xmlを使うよ。

```xml
<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.Splashanimationsample" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/purple_500</item>
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="colorOnPrimary">@color/white</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/teal_200</item>
        <item name="colorSecondaryVariant">@color/teal_700</item>
        <item name="colorOnSecondary">@color/black</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>

        <!-- ここから先を追加する -->
        <item name="android:windowSplashScreenIconBackgroundColor">#3DDC84</item>
        <item name="android:windowSplashScreenAnimatedIcon">@drawable/avd_anim</item>
        <item name="android:windowSplashScreenAnimationDuration">10000</item>
    </style>
</resources>
```

`android:windowSplashScreenIconBackgroundColor`はアイコン背景の色。
[公式ドキュメント](https://developer.android.google.cn/about/versions/12/features/splash-screen?hl=ja#elements)の②に当たる部分だね。

ここも元々入っている`ic_launcher_background.xml`を使いたかったんだけど、どうやら色しか設定できないみたい。
凝った背景にしたいなら、リソース作る段階で背景を入れておかないとダメっぽい。

`android:windowSplashScreenAnimatedIcon`はさっき作ったアイコンを設定する。
`android:windowSplashScreenAnimationDuration`はアニメーションさせる時間を設定する。

これでtheme.xmlの設定は完了！

## AndroidManifestでthemeを設定する。

あとはAndroidManifest.xmlで、作ったthemeを設定するだけ。

```xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.splash_animation_sample">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Splashanimationsample"><!-- こいつが入ってるのを確認する -->
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
```

themeを設定するのは、applicationでもactivityでもいいみたい。

これにて実装完了！🎉
やった〜

# まとめ

- Splashアイコンのアニメーションは意外と簡単に実装できる。
- AnimatedVectorDrawableも意外と簡単に作れる。

僕はAnimationDrawableを使おうと頑張って時間食っちゃったけど、最初からAnimatedVectorDrawableを使えば超簡単に実装できちゃいそうね。
今回はalphaだけの質素なアニメーションだったけど、プロジェクトに導入するときはGoogleアプリやYoutubeみたいなギュン！🌀って感じのやつ作りたいな。

作ったサンプルは[ここ](https://github.com/KKusumi/splash-animation-sample)にあるよ。
わからんかったら見てね。

終わり。

# 参考
- [スプラッシュ画面](https://developer.android.google.cn/about/versions/12/features/splash-screen?hl=ja)
- [ドローアブル グラフィックをアニメーションにする](https://developer.android.com/guide/topics/graphics/drawable-animation?hl=ja#AnimVector)

# おまけ

- 下位バージョンでも同一のSplash画面を表示したい場合は、[Splash Screen 互換ライブラリ](https://developer.android.com/guide/topics/ui/splash-screen/migrate)を使うといいらしい。