edge-to-edge が有効な画面ではステータスバーとナビゲーションバーが透明になり、コンテンツがステータスバーとナビゲーションバーの下生地として表示されます。edge-to-edge が有効な画面がどのように表示されるかは以下の記事を参照してください。
上の記事で紹介したが、Scaffold を使用するとコンテンツをステータスバーとナビゲーションバーと被らないように表示できる。Scaffold 直下の Composable 関数に色を付けてみる。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge() // edge-to-edge を有効にする。(Android 15 + API 35 は自動でedge-to-edge が強制される)
setContent {
HelloedgeTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Column(
modifier = modifier.fillMaxSize().background(color = Color.Cyan)
) {
Text(
text = "Hello $name!",
)
}
}
うーん、これだとステータスバーがただ透明になっただけで edge-to-edge の意味がない💦 edge-to-edge であるならコンテンツの背景とステータスバーの背景がシームレスにつながっている方が見栄えが良いだろう。
ステータスバーの背景を表示するため、まずトップの Composable 関数を Box
に、次に背景用の Composable 関数を配置する。この時、背景用の Composable 関数には Modifier.fillMaxSize()
を適用し、Scaffold
の innerPadding
は適用しないのがポイント。
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Box {
// 背景用の Composable 関数
Column(
modifier = Modifier.fillMaxSize().background(color = Color.Cyan)
) {}
// コンテンツ用の Composable 関数
Column(
modifier = modifier.fillMaxSize()
) {
Text(
text = "Hello $name!",
)
}
}
}
Scaffold
の innerPadding
を適用したコンテンツ用の Composable 関数は本当にステータスバーとナビゲーションバーに被らないのか確認してみる。コンテンツ領域がどこなのかわかるようコンテンツ用の Composable 関数に背景色 Color.Magenta
を追加してみる。
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Box {
// 背景用の Composable 関数
Column(
modifier = Modifier.fillMaxSize().background(color = Color.Cyan)
) {}
// コンテンツ用の Composable 関数
Column(
modifier = modifier.fillMaxSize().background(color = Color.Magenta)
) {
Text(
text = "Hello $name!",
)
}
}
}
コンテンツ用の Composable 関数はステータスバーとナビゲーションバーに被らないことが確認できた。
3ボタンナビゲーションの背景が半透明💦
上記はナビゲーションモードがジェスチャーナビゲーションの場合であるが、3ボタンナビゲーションに切り替えると半透明になる。
3ボタンナビゲーションの背景が半透明になる事象を解消するには、window.isNavigationBarContrastEnforced
プロパティを false
にする。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge() // edge-to-edge を有効にする。(Android 15 + API 35 は自動でedge-to-edge が強制される)
setContent {
HelloedgeTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ window.isNavigationBarContrastEnforced = false
+ }
}
}
}