Compose Multiplatformでテーマに同期してStatusBarのアイコン色を変更する
Katz
KALEIDOT.NET
※本記事ではEdge-to-edgeの説明には記載せず、理解している前提で解説を進めます。
targetSdkVersion36(Android 16)からはEdge-to-edgeがデフォルトで有効となり、そのためAndroidアプリ開発者はtargetSdkVersion36にアップデートする際にはEdge-to-edgeの対応が必要になります。
公式ドキュメントでは以下の3つのModifier修飾子をを用いてEdge-to-edge対応を進めるという記載があります。そのためAndroid開発者この3つのModifier修飾子を利用してEdge-to-edge対応を進めることになります。
ですがModifier修飾子について文面だけ見ても動作が理解しにくいところがあったので、どのような仕様・定義・動作をするものなのか調べてみました。
consumeWindowInsets
が使用されている場合、それらによってすでに消費されたインセットは、この修飾子では除外されます。/**
* Adds padding so that the content doesn't enter [insets] space.
*
* Any insets consumed by other insets padding modifiers or [consumeWindowInsets] on a parent
* layout will be excluded from [insets]. [insets] will be [consumed][consumeWindowInsets] for
* child layouts as well.
*
* For example, if an ancestor uses [statusBarsPadding] and this modifier uses
* [WindowInsets.Companion.systemBars], the portion of the system bars that the status bars uses
* will not be padded again by this modifier.
*
* @sample androidx.compose.foundation.layout.samples.insetsPaddingSample
* @see WindowInsets
*/
@Stable
fun Modifier.windowInsetsPadding(insets: WindowInsets): Modifier = composed(
debugInspectorInfo {
name = "windowInsetsPadding"
properties["insets"] = insets
}
) {
remember(insets) { InsetsPaddingModifier(insets) }
}
@Composable
fun InsetsModifierNestScreen(onClose: () -> Unit) {
BackHandler {
onClose()
}
Box(
modifier =
Modifier
.fillMaxSize()
.background(Color.Red.copy(alpha = 0.5f))
.windowInsetsPadding(WindowInsets.statusBars)
.windowInsetsPadding(WindowInsets.navigationBars),
) {
Box(
modifier =
Modifier
.fillMaxSize()
.background(Color.Blue.copy(alpha = 0.5f))
.windowInsetsPadding(WindowInsets.statusBars)
.windowInsetsPadding(WindowInsets.navigationBars),
) {
Box(
modifier =
Modifier
.fillMaxSize()
.background(Color.Green.copy(alpha = 0.5f)),
)
}
}
}
consumeWindowInsets
が使用されている場合、それによってすでに消費されたインセットは、この修飾子によるパディングから除外されます。WindowInsets.Companion.navigationBars
は子レイアウトに対しても消費されるため、子で再度同じインセットが適用されることはありません。/**
* Adds padding to accommodate the [navigation bars][WindowInsets.Companion.navigationBars] insets.
*
* Any insets consumed by other insets padding modifiers or [consumeWindowInsets] on a parent layout
* will be excluded from the padding. [WindowInsets.Companion.navigationBars] will be
* [consumed][consumeWindowInsets] for child layouts as well.
*
* For example, if a parent layout uses [systemBarsPadding], the
* area that the parent layout pads for the status bars will not be padded again by this
* [navigationBarsPadding] modifier.
*
* When used, the [WindowInsets][android.view.WindowInsets] will be consumed.
*
* @sample androidx.compose.foundation.layout.samples.statusBarsAndNavigationBarsPaddingSample
*/
fun Modifier.navigationBarsPadding() =
windowInsetsPadding(debugInspectorInfo { name = "navigationBarsPadding" }) { navigationBars }
@Composable
fun InsetsFuncNestScreen(onClose: () -> Unit) {
BackHandler {
onClose()
}
Box(
modifier =
Modifier
.fillMaxSize()
.background(Color.Red.copy(alpha = 0.5f))
.statusBarsPadding()
.navigationBarsPadding(),
) {
Box(
modifier =
Modifier
.fillMaxSize()
.background(Color.Blue.copy(alpha = 0.5f))
.statusBarsPadding()
.navigationBarsPadding(),
) {
Box(
modifier =
Modifier
.fillMaxSize()
.background(Color.Green.copy(alpha = 0.5f)),
)
}
}
}
windowInsetsPadding
に似ていますが、パディングを追加せずに、他のインセット修飾子によってまだ消費されていないインセットを消費します。/**
* Consume insets that haven't been consumed yet by other insets Modifiers similar to
* [windowInsetsPadding] without adding any padding.
*
* This can be useful when content offsets are provided by [WindowInsets.asPaddingValues].
* This should be used further down the hierarchy than the [PaddingValues] is used so
* that the values aren't consumed before the padding is added.
*
* @sample androidx.compose.foundation.layout.samples.consumedInsetsSample
*/
@Stable
fun Modifier.consumeWindowInsets(insets: WindowInsets): Modifier = composed(
debugInspectorInfo {
name = "consumeWindowInsets"
properties["insets"] = insets
}
) {
remember(insets) { UnionInsetsConsumingModifier(insets) }
}
@Composable
fun ConsumeScreen(onClose: () -> Unit) {
BackHandler {
onClose()
}
Box(
modifier =
Modifier
.fillMaxSize()
.background(Color.Red.copy(alpha = 0.5f))
.consumeWindowInsets(WindowInsets.statusBars)
.consumeWindowInsets(WindowInsets.navigationBars),
) {
Box(
modifier =
Modifier
.fillMaxSize()
.background(Color.Blue.copy(alpha = 0.5f))
.windowInsetsPadding(WindowInsets.statusBars)
.windowInsetsPadding(WindowInsets.navigationBars),
) {
Box(
modifier =
Modifier
.fillMaxSize()
.background(Color.Green.copy(alpha = 0.5f)),
)
}
}
}