Jetpack ComposeでStatus Barの色を変更したい

この記事をシェア
JetpackCompose一問一答

Jetpack ComposeでStatus Barの色を変更するには、AccompanistのSystem UI Controllerライブラリを使います。

コンポーザブルでStatus Barの色を変更すべき場面

Jetpack Composeでアプリを作っていると、以下のような理由から、Status Barの色をコンポーザブル関数内で変更したくなります。

画面遷移に合わせてStatus Barの色を変更したい

画像やビデオを表示する画面ではStatus Barを黒くする、など画面遷移に合わせてStatus Barの色を変えたい場面があります。Composeで画面遷移を実現している場合は、Status Barの色もコンポーザブル関数内から変更したくなります。

XMLのテーマを削除したい

ComposeアプリではMateral Designのテーマもコンポーザブルで設定するため、基本的にはXMLによるテーマの定義は不要になります。しかし、Composeの標準機能ではStatus Barの色を変更できないため、Status Barの色を設定するためだけにXMLによるテーマの定義が残ってしまいます。コンポーザブルのテーマとXMLのテーマの二重管理は避けたいので、この記事で紹介するAccompanistライブラリを使ってコンポーザブル内でStatus Barの色を設定することによって、XMLのテーマ定義を削除できます。

依存関係の追加

まずはbuild.gradle(:app)にAccompanistライブラリの依存関係を追加します。

implementation 'com.google.accompanist:accompanist-systemuicontroller:0.20.3'

AccompanistはJetpack Composeのバージョンに対応する複数のバージョンが用意されています。最新の対応状況はAccompanistのサイトで確認してください。記事執筆時点では、Jetpack Compose 1.0を使う場合はAccompanist 0.20.3を、Jetpack Compose 1.1を使う場合はAccompanist 0.23.1が最新となっています。

色の設定

Status Barの色を設定するには、SystemUiController#setStatusBarColor()を使います。SystemUiControllerオブジェクトは、rememberSystemUiController()で取得します。

import com.google.accompanist.systemuicontroller.rememberSystemUiController

fun AppScreen() {
    val systemUiController = rememberSystemUiController()
    SideEffect {
        systemUiController.setStatusBarColor(Color.Black)
    }

    ...
}

setStatusBarColor()は、コンポーザブル以外に影響を与える「副作用」ですので、SideEffectのスロット内に記述します。

setStatusBarColor()はどこで呼び出しても動作しますが、基本的にはひとつの画面を構成するコンポーザブル階層の一番上位のコンポーザブルに記述するのが良いと思います。アプリ内で画面によってStatus Barの色を変える場合は、各画面のコンポーザブルでそれぞれ色を指定してsetStatueBarColor()を呼び出します。

テーマカラーを指定する場合

Composeで定義したテーマカラーを取得するにはMaterialTheme.colorSchemeを参照しますが、SideEffectのスロットはコンポーザブルではないので、MaterialTheme.colorSchemeを参照できません。そこで、SideEffectの外でColorオブジェクトを取得します。

import com.google.accompanist.systemuicontroller.rememberSystemUiController

fun AppScreen() {
    val systemUiController = rememberSystemUiController()
    val statusBarColor = MaterialTheme.colorScheme.primaryContainer
    SideEffect {
        systemUiController.setStatusBarColor(statusBarColor)
    }

    ...
}
JetpackCompose一問一答

Jetpack Compose一問一答

コンテンツは随時追加していきます。

この記事をシェア