8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Jetpack ComposeでMaterial3のTopAppBarをStatusBarの下まで表示させる

Posted at

先日投稿した、Material 3で大きく変わったTopAppBarをJetpack Composeで実装してみる の補足記事になります。

前回の記事で紹介した androidx.compose.material3 の TopAppBar ですが、そのまま実装すると StatusBar の下まで表示させる Edge to edge の対応ができません。

androidx.compose.material の方は Accompanist の Inset がその辺りの実装をライブラリとして提供してくれていますが、androidx.compose.material3 の方は存在しない ( issue は立っている) ので実装が必要になります。

Accompanist で提供されそうな予感もしつつ、対応するための実装を書いていこうと思います。
(Accompanist の Inset 周りのコードの説明は省略します。)

TopAppBar に padding を設定しても背景色は適用されない

以下のコードのように TopAppBar に StatusBar の高さ分の padding を設定すると StatusBar の部分に空白ができるて背景色が反映されない状態になります。
Jetpack Compose の modifier の挙動ではあるものの、StatusBar の下まで TopAppBar の背景色を表示させたいのでこれだと対応が不十分です。

@Composable
fun ExampleScreen() {
    val statusBarPadding = rememberInsetsPaddingValues(
        LocalWindowInsets.current.statusBars,
        applyBottom = false,
    )
    val scrollBehavior = remember { TopAppBarDefaults.pinnedScrollBehavior() }
    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        topBar = {
            SmallTopAppBar(
                title = {
                    Text(text = "Title")
                },
                navigationIcon = {
                    BackIconButton {
                    }
                },
                scrollBehavior = scrollBehavior,
                modifier = Modifier.padding(statusBarPadding),
            )
        }
    ) {
        // contents
    }
}

実装

以下のようなコードで TopAppBar に padding を適用しても背景色が適用されるようにします

  • TopAppBar の背景色は透明にする
  • Surface 側で本来 TopAppBar で表示されるはずの背景色をセットする
  • 外から padding を設定できるようにして TopAppBar 側にセットする

(SmallTopAppBar のコードになりますが、Medium や Large も同じ要領で実装できます。)

@Composable
fun SmallTopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    contentPadding: PaddingValues = PaddingValues(0.dp),
    navigationIcon: @Composable () -> Unit = {},
    actions: @Composable RowScope.() -> Unit = {},
    colors: TopAppBarColors = TopAppBarDefaults.smallTopAppBarColors(),
    scrollBehavior: TopAppBarScrollBehavior? = null,
) {
    val backgroundColor = colors.containerColor(
        scrollFraction = scrollBehavior?.scrollFraction ?: 0.0f
    ).value
    Surface(
        color = backgroundColor,
        modifier = modifier,
    ) {
        androidx.compose.material3.SmallTopAppBar(
            title = title,
            navigationIcon = navigationIcon,
            actions = actions,
            scrollBehavior = scrollBehavior,
            colors = TopAppBarDefaults.smallTopAppBarColors(
                containerColor = Color.Transparent,
                scrolledContainerColor = Color.Transparent
            ),
            modifier = Modifier.padding(contentPadding),
        )
    }
}

ここで実装した TopAppBar を使うことで StatusBar の下まで TopAppBar を正しく表示させることができます。

@Composable
fun ExampleScreen() {
    val statusBarPadding = rememberInsetsPaddingValues(
        LocalWindowInsets.current.statusBars,
        applyBottom = false,
    )
    val scrollBehavior = remember { TopAppBarDefaults.pinnedScrollBehavior() }
    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        topBar = {
            SmallTopAppBar(
                title = {
                    Text(text = "Title")
                },
                navigationIcon = {
                    BackIconButton {
                    }
                },
                scrollBehavior = scrollBehavior,
                contentPadding = statusBarPadding,
            )
        }
    ) {
        // contents
    }
}
8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?