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
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
Fluid Templating in TYPO3 14
s2b
0
130
AWS re:Invent 2025参加 直前 Seattle-Tacoma Airport(SEA)におけるハードウェア紛失インシデントLT
tetutetu214
2
120
CSC307 Lecture 06
javiergs
PRO
0
690
OSSとなったswift-buildで Xcodeのビルドを差し替えられるため 自分でXcodeを直せる時代になっている ダイアモンド問題編
yimajo
3
620
AI時代の認知負荷との向き合い方
optfit
0
160
dchart: charts from deck markup
ajstarks
3
990
なるべく楽してバックエンドに型をつけたい!(楽とは言ってない)
hibiki_cube
0
140
疑似コードによるプロンプト記述、どのくらい正確に実行される?
kokuyouwind
0
390
組織で育むオブザーバビリティ
ryota_hnk
0
180
CSC307 Lecture 10
javiergs
PRO
1
660
MDN Web Docs に日本語翻訳でコントリビュート
ohmori_yusuke
0
650
React 19でつくる「気持ちいいUI」- 楽観的UIのすすめ
himorishige
11
7.4k
Featured
See All Featured
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
83
Building Applications with DynamoDB
mza
96
6.9k
Git: the NoSQL Database
bkeepers
PRO
432
66k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
120
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
100
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
200
Darren the Foodie - Storyboard
khoart
PRO
2
2.4k
Side Projects
sachag
455
43k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
54
The untapped power of vector embeddings
frankvandijk
1
1.6k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
590
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