Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Edge-to-Edge / WindowInsets との上手な付き合い方

Edge-to-Edge / WindowInsets との上手な付き合い方

Avatar for wcaokaze

wcaokaze

April 24, 2025
Tweet

More Decks by wcaokaze

Other Decks in Programming

Transcript

  1. Android 14以前のEdge-to-Edge • APIレベル 26(Android 8.0)以降 ◦ フル対応可能 • APIレベル

    25(Android 7.1)以前 ◦ ナビゲーションバーのアイコン色が白固定 • APIレベル 22(Android 5.1)以前 ◦ ステータスバーのアイコン色が白固定 • APIレベル 20(Android 4.4)以前 ◦ 割愛 12
  2. Android 14以前のEdge-to-Edge • APIレベル 26(Android 8.0)以降 ◦ フル対応可能 • APIレベル

    25(Android 7.1)以前 ◦ ナビゲーションバーのアイコン色が白固定 • APIレベル 22(Android 5.1)以前 ◦ ステータスバーのアイコン色が白固定 • APIレベル 20(Android 4.4)以前 ◦ 割愛 13 出典: 太宰治「走れメロス」
  3. Android 14以前のEdge-to-Edge • APIレベル 26(Android 8.0)以降 ◦ フル対応可能 • APIレベル

    25(Android 7.1)以前 ◦ ナビゲーションバーのアイコン色が白固定 • APIレベル 22(Android 5.1)以前 ◦ ステータスバーのアイコン色が白固定 • APIレベル 20(Android 4.4)以前 ◦ 割愛 14 出典: 太宰治「走れメロス」
  4. Android 14以前のEdge-to-Edge • APIレベル 26(Android 8.0)以降 ◦ フル対応可能 • APIレベル

    25(Android 7.1)以前 ◦ ナビゲーションバーのアイコン色が白固定 • APIレベル 22(Android 5.1)以前 ◦ ステータスバーのアイコン色が白固定 • APIレベル 20(Android 4.4)以前 ◦ 割愛 15 出典: 太宰治「走れメロス」
  5. Android 14以前のEdge-to-Edge • APIレベル 26(Android 8.0)以降 ◦ フル対応可能 • APIレベル

    25(Android 7.1)以前 ◦ ナビゲーションバーのアイコン色が白固定 • APIレベル 22(Android 5.1)以前 ◦ ステータスバーのアイコン色が白固定 • APIレベル 20(Android 4.4)以前 ◦ 割愛 16 出典: 太宰治「走れメロス」
  6. Android 14以前のEdge-to-Edge • APIレベル 26(Android 8.0)以降 ◦ フル対応可能 • APIレベル

    25(Android 7.1)以前 ◦ ナビゲーションバーのアイコン色が白固定 • APIレベル 22(Android 5.1)以前 ◦ ステータスバーのアイコン色が白固定 • APIレベル 20(Android 4.4)以前 ◦ 割愛 17 出典: 太宰治「走れメロス」
  7. Android 14以前のEdge-to-Edge • APIレベル 26(Android 8.0)以降 ◦ フル対応可能 • APIレベル

    25(Android 7.1)以前 ◦ ナビゲーションバーのアイコン色が白固定 • APIレベル 22(Android 5.1)以前 ◦ ステータスバーのアイコン色が白固定 • APIレベル 20(Android 4.4)以前 ◦ 割愛 18
  8. Android 14以前のEdge-to-Edge • APIレベル 26(Android 8.0)以降 ◦ フル対応可能 • APIレベル

    25(Android 7.1)以前 ◦ ナビゲーションバーのアイコン色が白固定 • APIレベル 22(Android 5.1)以前 ◦ ステータスバーのアイコン色が白固定 • APIレベル 20(Android 4.4)以前 ◦ 割愛 19 ⎫ ⎬ ⎭ 工夫が必要
  9. Android 14以前のEdge-to-Edge • APIレベル 26(Android 8.0)以降 ◦ フル対応可能 • APIレベル

    25(Android 7.1)以前 ◦ ナビゲーションバーのアイコン色が白固定 • APIレベル 22(Android 5.1)以前 ◦ ステータスバーのアイコン色が白固定 • APIレベル 20(Android 4.4)以前 ◦ 割愛 20 出典: 太宰治「走れメロス」
  10. Android 14以前のEdge-to-Edge • APIレベル 26(Android 8.0)以降 ◦ フル対応可能 • APIレベル

    25(Android 7.1)以前 ◦ ナビゲーションバーのアイコン色が白固定 • APIレベル 22(Android 5.1)以前 ◦ ステータスバーのアイコン色が白固定 • APIレベル 20(Android 4.4)以前 ◦ 割愛 21 出典: 太宰治「走れメロス」
  11. Android 14以前のEdge-to-Edge • APIレベル 26(Android 8.0)以降 ◦ フル対応可能 • APIレベル

    25(Android 7.1)以前 ◦ ナビゲーションバーのアイコン色が白固定 • APIレベル 22(Android 5.1)以前 ◦ ステータスバーのアイコン色が白固定 • APIレベル 20(Android 4.4)以前 ◦ 割愛 22 出典: 太宰治「走れメロス」
  12. Android 14以前のEdge-to-Edge APIレベル25(Android 7.1)以前をサポート しない場合 24 出典: 太宰治「走れメロス」 val windowInsetsController

    = WindowCompat.getInsetsController(window, window.decorView) windowInsetsController.isAppearanceLightStatusBars = true windowInsetsController.isAppearanceLightNavigationBars = true
  13. どれを使えばいい? ほぼsafeDrawing一択 38 出典: 太宰治「走れメロス」 Text( text = "メロスは激怒した。" +

    "必ず、かの邪智暴虐の王を除かなければならぬと決意した。", modifier = Modifier .align(Alignment.BottomCenter) .windowInsetsPadding(WindowInsets.navigationBars) ) ❌
  14. どれを使えばいい? ほぼsafeDrawing一択 39 出典: 太宰治「走れメロス」 Text( text = "メロスは激怒した。" +

    "必ず、かの邪智暴虐の王を除かなければならぬと決意した。", modifier = Modifier .align(Alignment.BottomCenter) .windowInsetsPadding(WindowInsets.navigationBars) ) ❌
  15. どれを使えばいい? ほぼsafeDrawing一択 40 出典: 太宰治「走れメロス」 Text( text = "メロスは激怒した。" +

    "必ず、かの邪智暴虐の王を除かなければならぬと決意した。", modifier = Modifier .align(Alignment.BottomCenter) .windowInsetsPadding(WindowInsets.navigationBars) ) ❌
  16. どれを使えばいい? ほぼsafeDrawing一択 41 出典: 太宰治「走れメロス」 Text( text = "メロスは激怒した。" +

    "必ず、かの邪智暴虐の王を除かなければならぬと決意した。", modifier = Modifier .align(Alignment.BottomCenter) .windowInsetsPadding( WindowInsets.safeDrawing.only(WindowInsetsSides.Bottom) ) ) ⭕
  17. 実践 画面上部(AppBar) windowInsetsを渡す 45 出典: 太宰治「走れメロス」 TopAppBar( title = {

    … }, navigationIcon = { … }, actions = { … }, windowInsets = WindowInsets.safeDrawing )
  18. 実践 画面上部(AppBar) windowInsetsを渡す 46 出典: 太宰治「走れメロス」 TopAppBar( title = {

    … }, navigationIcon = { … }, actions = { … }, windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top) )
  19. 実践 画面下部(LazyColumn) 51 出典: 太宰治「走れメロス」 LazyColumn( modifier = Modifier .windowInsetsPadding(

    WindowInsets.safeDrawing.only(WindowInsetsSides.Bottom) ) ) { items(...) { … } } ❌
  20. 実践 AppBarは左右端も避けなければならない 57 出典: 太宰治「走れメロス」 TopAppBar( title = { …

    }, navigationIcon = { … }, actions = { … }, windowInsets = WindowInsets.safeDrawing .only(WindowInsetsSides.Top) )
  21. 実践 AppBarは左右端も避けなければならない 58 出典: 太宰治「走れメロス」 TopAppBar( title = { …

    }, navigationIcon = { … }, actions = { … }, windowInsets = WindowInsets.safeDrawing .only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal) )
  22. 実践 背景色 63 出典: 太宰治「走れメロス」 Row( modifier = Modifier .windowInsetsPadding(

    WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal) ) .background(if (background) { backgroundColor } else { Color.Transparent }) .windowInsetsPadding( WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal) ) ) { … }
  23. まとめ • (Jetpack Composeが動作する)すべての機種でEdge-to-Edgeを利用できる ◦ Android 7.1以前は工夫が必要 • Edge-to-Edgeに対応するためにはComposableがWindowInsetsと 重ならないようにレイアウトしなければならない

    • WindowInsetsと重なってはいけないComposable ◦ ユーザーが見ているコンテンツ(画像、文字など) ◦ ユーザーが操作するもの(ボタンなど) • WindowInsetsと重なってもいいComposable ◦ スクロール可能なもの ◦ 部分的に隠れても機能が失われないもの(区切り線、背景色など) 66