0
2

edge-to-edge が有効な画面でステータスバーとナビゲーションバーに描画する[Compose編]

Last updated at Posted at 2024-07-19

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() を適用し、ScaffoldinnerPadding は適用しないのがポイント。

@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!",
            )
        }
    }
}

ScaffoldinnerPadding を適用したコンテンツ用の 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
+           }

        }
    }
}
0
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
0
2