55

この記事は最終更新日から1年以上が経過しています。

【Flutterでの実装例つき】クロスプラットフォーム環境でアプリ起動時のSplash画面(Launch画面)を作成する方法

この記事は全部俺 Advent Calendar 2018の2日目の記事です。
頑張っていきます。

この記事で説明すること

このようなSplash画面(Launch画面)を作るとき、FlutterやReactNativeではどうやって作成するのかについて記載します。

オリジナルのGopherくんは、Renée Frenchによってデザインされました。

Splash画面の種類について

Splash画面は、大きく分けて次の2種類に大別できます。
(名称はマテリアルデザインのものになります。)

  • Branded launch screen
    • アプリ起動ボタンが押された後、アプリが起動するまでの間に表示されるSplash画面
  • Placeholder UI
    • 画面内でリソース読み込みなどを行っている間に表示されるSplash画面
    • Google画像検索やInstagramで画像読み込み中に表示される画面

左:Branded launch screen, 右:Placeholder UI
(material.ioより画像をお借りしました)

この記事では、Branded launch screenをクロスプラットフォーム環境で実装する方法について記載します。

クロスプラットフォーム開発におけるSplash画面の実装方針

結論から言うと、それぞれのプラットフォームごとにSplash画面を実装する必要があります。
クロスプラットフォーム開発なのにそれぞれのプラットフォームごとにSplash画面を実装しなければならない理由には、クロスプラットフォームにおける実行環境が関わっています。

FlutterやReactNativeは、AndroidとiOS上で起動する実行環境上で動作しています。
実際にアプリが起動する際は、以下のような順番で処理が行われることになります。

  1. アプリのアイコンがタップされ、Branded launch screenが表示される
  2. クロスプラットフォームの実行環境の立ち上げが行われる(FlutterならDart VM、ReactNativeなら JavaScript Runtime Environment)
  3. それぞれのクロスプラットフォーム上でコードが実行される

つまり、1. の時点ではクロスプラットフォーム実行環境が立ち上がっていないため、Branded launch screenを表示するコードをクロスプラットフォーム実行環境の上で記載することはできません!
(Placeholder UIについては記載することができます。)

以上の理由から、それぞれのプラットフォームごとにSplash画面を実装する必要があるのです。
注)Branded launch screenについては、読み込み時間を秒数で指定して表示することもできますが、UXを下げる原因になりうるので、この記事ではあくまでも実行環境の立ち上げまでの間に画面を表示することについて記載します。(Twitterを開く度に2秒間待たされる、という状況を考えるとうんざりしますよね?)

FlutterにおけるSplash画面の実装例

上記の理由から、Splash画面の実装はAndroidとiOS双方で行う必要があるわけですが、実装はそこまで難しくありません。
それぞれのプラットフォームで表示したい画像を用意して決められた場所に配置し、設定ファイルを書き換えることになります。
ここではFlutterを想定した実装例を記載しますが、ReactNativeなどの他プラットフォーム開発においても同様に実装すればOKです。

Android側の実装

画像ファイルの配置

下記のmipmap-xxxxディレクトリに、同名で作成したファイル(ここではlaunch_splash.png)を配置します。

styles.xmlの編集

背景色をHexカラーコードでandroid/app/src/main/res/values/styles.xmlに定義します。

styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
        <item name="android:windowBackground">@drawable/launch_background</item>
    </style>
    <color name="background">#84ffff</color>
</resources>

launch_background.xmlの編集

上記で作成・定義した画像ファイルと背景色をandroid/app/src/main/res/drawable/launch_background.xmlに定義します。

launch_background.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:drawable="@color/background"/>

    <item
        android:width="200dp"
        android:height="200dp"
        android:drawable="@mipmap/launch_splash"
        android:gravity="center" />
</layer-list>

buildして動作確認

buildして実行すると、以下のようなBranded launch screenが表示されます。

アプリがメモリに残っているときにアプリ履歴から起動した場合は、Branded launch screenはもちろん表示されません。

iOS側の実装

画像ファイルの配置

XCodeからRunner.xcworkspaceを開き、Assets.xassets上のLaunchImageに画像をドラッグ&ドロップで配置します。

LaunchScreen.storyboardの編集

「LaunchScreen.storyboard」→「View」→「Background」から「Custom」を選択し、Hexカラーコードで色を指定します。

必要であれば制約条件を追加します。
例えば、画面幅の0.5倍のサイズで中央に画像が表示されるように設定する方法は以下のようになります。

  1. ViewとLaunchImageを選択して、画面右下の制約条件から「Equal Widths」を選択して「Add 1 Constraint」
  2. 作成した制約条件を選び、「Multiplier」の値を「0.5」に変更

buildして動作確認

buildして実行すると、以下のようなBranded launch screenが表示されます。

アプリがメモリに残っているときにアプリ履歴から起動した場合は、Branded launch screenはもちろん表示されません。

まとめ

  • Splash画面はBranded launch screenとPlaceholder UIの2種類ある
  • クロスプラットフォーム開発において、Branded launch screenはネイティブ実装を行う必要がある

ハマりどころ

  • iOSのLaunchScreenが更新されないとき
    • キャッシュが残ってしまっている可能性があるので、simulatorをrestartすると良いです。
    • Cleanだけでは直らない場合があります。
  • Flutterにおいて、Android/iOSのBranded launch screenとFlutterのmain.dart画面の間に一瞬黒い画面が表示される場合
    • Flutterのバージョンによるバグです。
      • コマンドラインからflutter upgradeでアップグレードすれば直ります。
    • Branded launch screenとFlutterのmain.dartの間に、dart実行環境の立ち上げが挟まっているために起きていたようです。
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
tez
libora
e-Learning一括検索サービス『LIBORA』の開発・運営を行っています。
この記事は以下の記事からリンクされています

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
記事投稿イベント開催中
Azure IoTに関する記事を投稿しよう!
~