はじめに
画面によってstatus barの色を変える方法です。
Android JetPackのNavigationを使っている場合にフォーカスして記載します。
Navigationは1.0.0-alpha05
を使用しています。
イメージはこんな感じです。
サンプルに使用した元のアプリはNavigationのcodelabのものを使わせていただきました。
https://github.com/googlecodelabs/android-navigation
対応方法
順を追って説明しますが、対応手順は3つです。
1.ステータスバーの色定義
やり方は色々あるかと思いますが、整理しやすいようにここではステータスバーの色をenumで定義しました。
enum class StatusBarColor(private val key: String, val color: Int) {
BLUE("blue", android.R.color.holo_blue_dark),
RED("red", android.R.color.holo_red_dark),
BLACK("black", android.R.color.black);
companion object {
fun findByKey(key: String?): StatusBarColor =
StatusBarColor.values().find { it.key == key } ?: BLACK
}
}
findByKey
は、引数はnullableで、戻り値はnon-nullにした方が後々便利です。
2.各Fragmentにステータスバーの色を定義
Navigationのxmlにおいて、各Fragmentのargumentにステータスバーの色情報を与えます。コード上でこれを参照して、ステータスバーの色を変えます。
<navigation ...>
<fragment ...>
<argument
android:name="statusBarColor"
android:defaultValue="blue"
app:argType="string" />
...
</fragment>
<fragment ...>
<argument
android:name="statusBarColor"
android:defaultValue="red"
app:argType="string" />
...
</fragment>
...
</navigation>
-
android:name
: コード上でargumentから値を取り出すときに使います -
android:defaultValue
: 先ほど定義したStatusBarColor
のkey
を指定します -
app:argType
: 文字列(string
)として定義します。先頭の「s」は小文字なのでご注意を。
3.NavControllerにリスナー設定
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...(略)
findNavController(R.id.my_nav_host_fragment).addOnNavigatedListener { _, destination ->
// argumentからstatus barの色情報を取得する
val statusBarColor = StatusBarColor.findByKey(destination.defaultArguments.getString("statusBarColor"))
// status barの色を変更
window.statusBarColor = ContextCompat.getColor(this, statusBarColor.color)
}
}
NavController
に対してOnNavigatedListener
を設定します。これにより、Navigationでの画面遷移完了時に通知を受け取ることができます。その際、引数でNavDestination
が受け取れます。このNavDestination
は画面遷移したFragmentの情報を持っており、ここに上で定義したargument
も含まれています。
よって、このdestination
からdefaultArguments.getString
でString値を取り出し、StatusBarColor
へと変換します。
このとき、string値がnullだったり、argumentに定義がなかったりした場合でも、StatusBarColor.findByKey
の引数がnullableで戻り値がnonnullだと、便利に使えます。
あとは、StatusBarColor
のcolorResIdを使って実際にステータスバーの色を変えるだけで完了です。