2013/03/27

Androidでスプラッシュ画面を表示する

何番煎じかわかりませんが、Androidでスプラッシュを表示する方法です。

スプラッシュを実現するにあたって、編集するファイルは

  • 一番最初に表示するActivity(MainActivity.java)
  • アクティビティのxmlファイル(activity_main.xml)

の2つです。

まずxmlファイルの方を編集していきます。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:animateLayoutChanges="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        // アクティビティに表示するコンポーネントをここに書く
        
    </LinearLayout>

    <ImageView
        android:id="@+id/splash_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:contentDescription="@string/content_description_splash"
        android:scaleType="fitXY"
        android:src="@drawable/splash" />

</FrameLayout>

一番外側をFrameLayoutでラップして、通常の画面の上にSplash画像が重なるようにします。

android:animateLayoutChanges="true"

これは、レイアウトが変更されるときにアニメーションするかどうかを設定しています。
フェードアウトしたほうが綺麗なので、trueに設定しています。(APILevel11以上の時なので,2.xではアニメーションしません)

次に、MainActivity.javaの方を編集します。
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.actiivty_main);
        
        initSplashView();
        
        SplashClearTask splashClearTask = new SplashClearTask();
        splashClearTask.execute();
    }
    
    private void initSplashView() {
        ImageView splashView = (ImageView)findViewById(R.id.splash_view);
        // スプラッシュ表示中はクリックを無視する
        splashView.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View v) {
                return;
            }
        });
    }

    private void clearSplash() {
        ImageView splashView = (ImageView)findViewById(R.id.splash_view);
        splashView.setVisibility(View.GONE);
    }

    private class SplashClearTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {
            try {
                // 一定時間待機
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            clearSplash();
        }
    }

ポイントは、スプラッシュ表示中のクリックを無効化している部分と、SplashClearTaskの部分です。

FrameLayoutでViewを重ねるだけでは、その下にあるViewをクリックできてしまうので、スプラッシュ画像が表示されている間、その下にあるコンポーネントをクリックできないようにしています。

SplashClearTaskでは、スプラッシュを一定時間表示してからスプラッシュを消すためにdoInBackgroundでThread.sleep()を使っています。

アクティビティのレイアウトの階層が1段深くなりますが、スプラッシュ用にアクティビティを使わなくてすみます。

注意するポイントとしては、アクションバーやメニューバーは表示されてしまうので、スプラッシュの前後で表示の切替が必要です。