Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Edge-to-Edge / WindowInsets との上手な付き合い方
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
wcaokaze
April 24, 2025
Programming
0
86
Edge-to-Edge / WindowInsets との上手な付き合い方
https://youtu.be/j5ckxa6_2gc
wcaokaze
April 24, 2025
Tweet
Share
More Decks by wcaokaze
See All by wcaokaze
Composeのイベント地獄から脱出しよう! The Elm Architectureの導入にみる可能性
wcaokaze
0
110
Jetpack Composeで拡大縮小、斜め方向のスクロールを実装する
wcaokaze
0
560
Other Decks in Programming
See All in Programming
CSC307 Lecture 02
javiergs
PRO
1
780
高速開発のためのコード整理術
sutetotanuki
1
400
Grafana:建立系統全知視角的捷徑
blueswen
0
330
疑似コードによるプロンプト記述、どのくらい正確に実行される?
kokuyouwind
0
390
AI巻き込み型コードレビューのススメ
nealle
2
420
AIによる高速開発をどう制御するか? ガードレール設置で開発速度と品質を両立させたチームの事例
tonkotsuboy_com
7
2.4k
余白を設計しフロントエンド開発を 加速させる
tsukuha
7
2.1k
CSC307 Lecture 07
javiergs
PRO
1
550
Claude Codeと2つの巻き戻し戦略 / Two Rewind Strategies with Claude Code
fruitriin
0
140
そのAIレビュー、レビューしてますか? / Are you reviewing those AI reviews?
rkaga
6
4.6k
KIKI_MBSD Cybersecurity Challenges 2025
ikema
0
1.3k
Data-Centric Kaggle
isax1015
2
780
Featured
See All Featured
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
100
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
450
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
350
Building an army of robots
kneath
306
46k
Six Lessons from altMBA
skipperchong
29
4.2k
Navigating Weather and Climate Data
rabernat
0
110
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
0
3.4k
Believing is Seeing
oripsolob
1
56
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
130
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
0
1.1k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
120
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