メモ2ブログ

メモtoウェブログ。旧ブログはこちら。 http://sakebook.blogspot.jp/

スプラッシュにはActivityはいらない

スプラッシュ

iOSだとLaunchScreenとか言われる、起動時に出てくる画面です。

Androidだと、ユーザに無駄な待ち時間を与えるということで不要だと言われてたのですが、最近はGoogle製のアプリが、軒並みスプラッシュを入れてきています。

Bottom Navigationのことといい、考え方が変わってきたのでしょう。 Android開発を行う以上、プラットフォームが出すガイドラインに合わせるのが、結果的にユーザに良い体験を与えることにつながります。

スプラッシュについては、iOSと同様に、LaunchScreenというPatternで紹介されています。その実装方法を紹介します。

Activityあり

f:id:sakebook:20160601030423g:plain

SplashActivityなどを用意して、起動時に呼び出します。 なんらかの処理や、一定時間を経過した後にメインのActivityを起動させます。

  • DelaySplashActivity.java
public class DelaySplashActivity extends AppCompatActivity {

    private final static int SPLASH_TIME = 1500;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_delay_splash);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(DelaySplashActivity.this, MainActivity.class);
                startActivity(intent);
                finish();
            }
        }, SPLASH_TIME);
    }

    /**
     * バックキー無効。
     * */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            return false;
        }
        return super.onKeyDown(keyCode, event);
    }
}

この方法だと、次のような特徴があります。

長所

  • DelaySplashActivityを起動させている間に処理を実行することができる
  • 複雑なアニメーションなどを表現できる

短所

  • 起動時間が若干遅くなる
  • LaunchModeをうまく指定しないとメインのActivityが重複する
  • 起動時に数瞬ブランクが表示される

Activityなし

f:id:sakebook:20160601030502g:plain

新たにActivityは追加しません。 Themeを指定します。

    <style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@drawable/background_splash</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

親となるテーマのActionBarの有無は用途によって変えてください。
重要なのは android:windowBackground属性にdrawableを指定していることです。

background_splashは次のように設定しています。

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

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

    <item
        android:gravity="center">
        <bitmap
            android:gravity="center"
            android:src="@mipmap/ic_launcher"/>
    </item>
    <item
        android:gravity="bottom"
        android:bottom="@dimen/large_margin">
        <bitmap
            android:gravity="center"
            android:src="@mipmap/ic_launcher"/>
    </item>

</layer-list>

layer-listで作成します。

文字は追加できないのですが、Verctor画像で文字を作れば設定できます
その場合はstyleをv21以降と以前で分ける必要があります。

起動するActivityに作成したテーマを設定します。

  • AndroidManifest.xml
        ...
        <activity
            android:name=".SplashActivity"
            android:label="SplashCold"
            android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

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

Splash専用のActivityを追加しなくても、スプラッシュが追加できています!

この方法だと次のような特徴があります。

長所

  • 起動時間が通常とほぼ変わらない
  • 既存のアプリに追加しやすい
  • 起動時に数瞬ブランクが表示されない

短所

  • 事前の処理が行えない
  • 表現できることに制約がある

まとめ

スプラッシュの目的はplaceholder UIBranded launch screensです。

特に理由が無ければ、Acitvityを追加しないSplashの実装で上記の目的を達成するのが良いと思います。
ただし、事前の処理を行っておくことで結果的にユーザ体験を良くできるならば、Activityを追加する実装でも良いと思います。
その場合はbackgroundの要素を指定しておきましょう。

サンプルです。

github.com

参考

Android UI/UX アンチパターン / nein37’s diary

Launch screens / Google design guidelines

プレースホルダ 【 placeholder 】 / IT用語辞典 e-Words

Splash Screens the Right Way / Big Nerd Ranch

Avoiding cold starts on Android / Saúl Molinero