はじめまして、初投稿です!
まだまだ未熟な学生プログラマですが、頑張ります。
スプラッシュを考える
さて、アプリをつくるぞー、となった時にまず考えてしまうのがスプラッシュ画面です。
これまでボタンを配置するようにsetContentView()
で表示していました。
とくに考えることもなく実装できたので、これでいいやと思ってました。
しかしそれでは**ユーザー体験が悪くなる!**と有識者からお聞きして、心機一転、setTheme()
でのスプラッシュ実装をするようになりました。
そうなるまでの紆余曲折をレポートします!
setContentView()でやってること
いつものやつです。レイアウトファイルを読み込んで、Viewを配置してくれます。
setTheme()
との大きな違いは、表示するものがViewであることだと思います。
setTheme()でやっていること
そのActivityのテーマをセットしてくれます。setContentView()
とのちがいは、アプリ起動した瞬間の挙動です。
通常、setContentView()
では
[アプリ起動]->[onCreate]->[Themeの確定]->[setContentView]->スプラッシュのView表示
この[Themeの確定]でデフォルトだと真っ白(黒)な画面ですので、アプリ起動すると一瞬それが見えます。起動時の処理が重いと、アプリ起動してからしばらくそれが見れるはずです。
これをsetTheme()
を使うと、
[アプリ起動]->[onCreate]->[setTheme]->スプラッシュ画面表示->[setContentView]->View表示
となり、起動時の処理に左右されず、アプリ起動してからスプラッシュ画面までの反応が早いです。これでユーザーの体験がよくなるわけですね。
注意点
setTheme()
でスプラッシュ画面を実装すると、Activityの画面遷移のようなアニメーションが適用されなくなります。
実装例
@yamikoo@github 様の記事を参考にさせていただきました。
私が実装を試した際にハマった点もふまえて記事にいたします。
https://qiita.com/yamikoo@github/items/c82ea335968709a9d32a
おおまかには
- drawable内に新規XMLファイル作成
- styles.xmlの編集
- Manifestファイルの編集
- Activityの編集
が必要です。
手順① drawable内に新規XMLファイルをつくる
res/drawableに新しくXMLファイルを作ります。
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:opacity="opaque"
android:layout_width="match_parent"
android:layout_height="match_parent">
<item
android:drawable="@color/splashBackground"/>
<item>
<bitmap
android:gravity="center"
android:src="@drawable/splash_img" />
</item>
</layer-list>
手順② styles.xmlの編集
res/values/styles.xmlに新しくスタイルを追加します。今回はSplashThemeとしました。
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
<style name="SplashTheme" parent="AppTheme">
<item name="android:windowBackground">@drawable/splash</item>
</style>
</resources>
手順③ Manifestファイルの編集
先ほど追加したスタイルを設定します。
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
手順④ Activityの編集
ポイントしては、Thread.sleep(1000)
で一秒間スプラッシュ画面が出るように設定しています。そして一秒後に元のテーマに戻しています。私の場合は元々R.style.AppTheme_NoActionBar
でした。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// splash
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
setTheme(R.style.AppTheme_NoActionBar);
setContentView(R.layout.activity_main);
/**** Do something... ****/
}
これで実装できました。
ハマったところ
スプラッシュ画面のサイズがおかしい(おかしくない)
今回スプラッシュ用にPNG形式(265x470)を用意しました。
ImageViewであればプロパティでmatch_parent
とかやれば、画面いっぱいに画像を出してくれましたが、そうはいきません。
作ったXMLファイルをもう一度見ていただければわかりますが、画像はbitmapとして定義されています。このためサイズ通り表示されます。
<bitmap
android:gravity="center"
android:src="@drawable/splash_img" />
私は265x470の画像を使ったので、画面いっぱいに表示されませんでした。そうすると、余白ができてしまいます。
これを回避する方法がさまざま検討されているようですが、結局ムリそうです。
https://stackoverflow.com/questions/23079355/android-bitmap-image-size-in-xml
何かいい方法がありましたら教えてください。
回避方法(?)
なにも回避できていませんが、私はこうしました。
もう一度splash.xmlを見てください。
<item
android:drawable="@color/splashBackground"/>
colors.xmlに新しくsplashBackgroundを定義して、余白の色を設定しました。
こうするとそれっぼく見えます。
さいごに
ユーザー体験を意識するのは大変ですが、少しでも良くしていきたいですね。
参考
@yamikoo@github 様
タイトル:Android スプラシュ画面の実装
https://qiita.com/yamikoo@github/items/c82ea335968709a9d32a
https://stackoverflow.com/questions/23079355/android-bitmap-image-size-in-xml