Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Edge-to-Edge / WindowInsets との上手な付き合い方
Search
wcaokaze
April 24, 2025
Programming
160
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Edge-to-Edge / WindowInsets との上手な付き合い方
https://youtu.be/j5ckxa6_2gc
wcaokaze
April 24, 2025
More Decks by wcaokaze
See All by wcaokaze
ブースアプリ開発裏話 〜pixivCanvasができるまで〜
wcaokaze
0
24
Compose時代に再検討するロードUIとその設計
wcaokaze
0
71
Composeのイベント地獄から脱出しよう! The Elm Architectureの導入にみる可能性
wcaokaze
0
160
Jetpack Composeで拡大縮小、斜め方向のスクロールを実装する
wcaokaze
0
610
Other Decks in Programming
See All in Programming
AIで開発が速くなった先で、開発チームは何を目指すか
shihochan
1
1.8k
Event is what happens
moro
2
1.4k
続・コーディングルールの鮮度を保ちたい / keep-fresh-go-internal-conventions-again
handlename
0
110
[2026-10-14](C)Re:ゼロから始める異世界生活〜始まりの終わりと終わりの始まり〜
tosite
0
150
AIに “答え“を書かせるのを やめてみた
___akari11
0
130
phperだってパンチカードでコーディングしたい
o0h
PRO
0
410
AI時代のTerminal環境を UNIX哲学で設計・運用する
yasunori0418
1
210
Simple Storage Service(S3) is not simple
iwatsukayura
0
320
Groovy as a human and AI friendly programming language
paulk
0
110
個人開発者よ、Honoを使え(おじさんver)
tanahiro2010
2
270
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
1.3k
No More NoSuchMethodError
exoego
1
110
Featured
See All Featured
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
4
4.4k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
7k
Docker and Python
trallard
47
4.2k
Making Projects Easy
brettharned
120
6.8k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
330
Product Roadmaps are Hard
iamctodd
55
13k
Writing Fast Ruby
sferik
630
63k
HDC tutorial
michielstock
2
970
Building a Scalable Design System with Sketch
lauravandoore
464
34k
A designer walks into a library…
pauljervisheath
211
25k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
77k
Transcript
Edge-to-Edge / WindowInsetsとの 上手な付き合い方 @wcaokaze
自己紹介 • wcaokaze(わかおかぜ) • Palcy Android 2
Edge-to-Edgeとは? 3
Edge-to-Edgeとは? 画面の端から端までアプリの領域に なる 4 出典: 太宰治「走れメロス」
SDK35以降、強制される 5
SDK35以降Edge-to-Edge強制 35以降でも無効化する方法があるらしいが…? 6
SDK35以降Edge-to-Edge強制 35以降でも無効化する方法があるらしいが…? 今回は無効化しない場合の話 7
SDK35以降Edge-to-Edge強制 より厳密には? 8
SDK35以降Edge-to-Edge強制 より厳密には? 下記条件を満たすとEdge-to-Edgeが有効化される • targetSdk 35以降でビルドしたアプリ • Android 15以降で実行 9
SDK35以降Edge-to-Edge強制 ただし、これはEdge-to-Edgeが「強制される」条件。 この条件を満たさなくてもEdge-to-Edgeにすることは可能 10
SDK35以降Edge-to-Edge強制 ただし、これはEdge-to-Edgeが「強制される」条件。 この条件を満たさなくてもEdge-to-Edgeにすることは可能 どのみち対応するのであればAndroid 14以前でもEdge-to-Edgeにしたい 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)以前 ◦ 割愛 12
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 出典: 太宰治「走れメロス」
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 出典: 太宰治「走れメロス」
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 出典: 太宰治「走れメロス」
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 出典: 太宰治「走れメロス」
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 出典: 太宰治「走れメロス」
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
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 ⎫ ⎬ ⎭ 工夫が必要
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 出典: 太宰治「走れメロス」
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 出典: 太宰治「走れメロス」
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 出典: 太宰治「走れメロス」
Android 14以前のEdge-to-Edge APIレベル25(Android 7.1)以前をサポート しない場合 23 出典: 太宰治「走れメロス」
Android 14以前のEdge-to-Edge APIレベル25(Android 7.1)以前をサポート しない場合 24 出典: 太宰治「走れメロス」 val windowInsetsController
= WindowCompat.getInsetsController(window, window.decorView) windowInsetsController.isAppearanceLightStatusBars = true windowInsetsController.isAppearanceLightNavigationBars = true
Edge-to-Edge対応とは? 25
Edge-to-Edge対応とは? Edge-to-Edgeを有効化してみる 26 出典: 太宰治「走れメロス」
Edge-to-Edge対応とは? Edge-to-Edgeを有効化してみる 27 出典: 太宰治「走れメロス」
Edge-to-Edge対応とは? 画面端のUIがシステムバー等とカブらないように レイアウトする 28 出典: 太宰治「走れメロス」
WindowInsets 29
WindowInsets 画面端にあるものの大きさを知ることができる 30 WindowInsets( left = 0dp, top = 56dp,
right = 0dp, bottom = 48dp )
WindowInsets WindowInsets.statusBars 31
WindowInsets WindowInsets.navigationBars 32
WindowInsets WindowInsets.displayCutout 33
WindowInsets WindowInsets.ime 34
WindowInsets WindowInsets.safeDrawing 35
WindowInsets WindowInsets.safeGestures 36
どれを使えばいい? ほぼsafeDrawing一択 37
どれを使えばいい? ほぼsafeDrawing一択 38 出典: 太宰治「走れメロス」 Text( text = "メロスは激怒した。" +
"必ず、かの邪智暴虐の王を除かなければならぬと決意した。", modifier = Modifier .align(Alignment.BottomCenter) .windowInsetsPadding(WindowInsets.navigationBars) ) ❌
どれを使えばいい? ほぼsafeDrawing一択 39 出典: 太宰治「走れメロス」 Text( text = "メロスは激怒した。" +
"必ず、かの邪智暴虐の王を除かなければならぬと決意した。", modifier = Modifier .align(Alignment.BottomCenter) .windowInsetsPadding(WindowInsets.navigationBars) ) ❌
どれを使えばいい? ほぼsafeDrawing一択 40 出典: 太宰治「走れメロス」 Text( text = "メロスは激怒した。" +
"必ず、かの邪智暴虐の王を除かなければならぬと決意した。", modifier = Modifier .align(Alignment.BottomCenter) .windowInsetsPadding(WindowInsets.navigationBars) ) ❌
どれを使えばいい? ほぼsafeDrawing一択 41 出典: 太宰治「走れメロス」 Text( text = "メロスは激怒した。" +
"必ず、かの邪智暴虐の王を除かなければならぬと決意した。", modifier = Modifier .align(Alignment.BottomCenter) .windowInsetsPadding( WindowInsets.safeDrawing.only(WindowInsetsSides.Bottom) ) ) ⭕
実践 42
実践 画面端のUIがシステムバー等とカブらないように レイアウトする 43 出典: 太宰治「走れメロス」
実践 画面上部(AppBar) 44 出典: 太宰治「走れメロス」 TopAppBar( title = { …
}, navigationIcon = { … }, actions = { … }, )
実践 画面上部(AppBar) windowInsetsを渡す 45 出典: 太宰治「走れメロス」 TopAppBar( title = {
… }, navigationIcon = { … }, actions = { … }, windowInsets = WindowInsets.safeDrawing )
実践 画面上部(AppBar) windowInsetsを渡す 46 出典: 太宰治「走れメロス」 TopAppBar( title = {
… }, navigationIcon = { … }, actions = { … }, windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top) )
実践 画面内のすべてのComposableに同様の対応を 行う 47 出典: 太宰治「走れメロス」
No 48
WindowInsetsと重なってもいい Composableもある 49
実践 画面下部(LazyColumn) 50 出典: 太宰治「走れメロス」 LazyColumn { items(...) { …
} }
実践 画面下部(LazyColumn) 51 出典: 太宰治「走れメロス」 LazyColumn( modifier = Modifier .windowInsetsPadding(
WindowInsets.safeDrawing.only(WindowInsetsSides.Bottom) ) ) { items(...) { … } } ❌
実践 LazyColumnはスクロールが可能なため、 WindowInsetsと重ねることができる 52 出典: 太宰治「走れメロス」 LazyColumn { items(...) {
… } }
実践 LazyColumnはスクロールが可能なため、 WindowInsetsと重ねることができる 53 出典: 太宰治「走れメロス」 LazyColumn { items(...) {
… } }
実践 一番下までスクロールしたときには WindowInsetsと重なってはいけない 54 出典: 太宰治「走れメロス」 LazyColumn { items(...) {
… } }
実践 一番下までスクロールしたときには WindowInsetsと重なってはいけない 55 出典: 太宰治「走れメロス」 LazyColumn( contentPadding = WindowInsets.safeDrawing
.only(WindowInsetsSides.Bottom) .asPaddingValues() ) { items(...) { … } }
実践 左右端 56 出典: 太宰治「走れメロス」
実践 AppBarは左右端も避けなければならない 57 出典: 太宰治「走れメロス」 TopAppBar( title = { …
}, navigationIcon = { … }, actions = { … }, windowInsets = WindowInsets.safeDrawing .only(WindowInsetsSides.Top) )
実践 AppBarは左右端も避けなければならない 58 出典: 太宰治「走れメロス」 TopAppBar( title = { …
}, navigationIcon = { … }, actions = { … }, windowInsets = WindowInsets.safeDrawing .only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal) )
実践 LazyColumn部分も同様に 左右のWindowInsetsを避ける 59 出典: 太宰治「走れメロス」
No 60
WindowInsetsと重なってもいい Composableもある 61
実践 区切り線 62 出典: 太宰治「走れメロス」 HorizontalDivider( modifier = Modifier .windowInsetsPadding(
WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal) ) )
実践 背景色 63 出典: 太宰治「走れメロス」 Row( modifier = Modifier .windowInsetsPadding(
WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal) ) .background(if (background) { backgroundColor } else { Color.Transparent }) .windowInsetsPadding( WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal) ) ) { … }
完成! 64 出典: 太宰治「走れメロス」
まとめ 65
まとめ • (Jetpack Composeが動作する)すべての機種でEdge-to-Edgeを利用できる ◦ Android 7.1以前は工夫が必要 • Edge-to-Edgeに対応するためにはComposableがWindowInsetsと 重ならないようにレイアウトしなければならない
• WindowInsetsと重なってはいけないComposable ◦ ユーザーが見ているコンテンツ(画像、文字など) ◦ ユーザーが操作するもの(ボタンなど) • WindowInsetsと重なってもいいComposable ◦ スクロール可能なもの ◦ 部分的に隠れても機能が失われないもの(区切り線、背景色など) 66
Q. 大変じゃないですか? A. そうですね・・・ 67
Q. 大変じゃないですか? A. そうですね・・・ Android Studioのプレビュー機能を活用して かなり軽減できるので見てみてください https://inside.pixiv.blog/2025/03/26/163000 68
ありがとうございました 69