It’s finally time to go
Edge to Edge
Hugo Visser
hugo@littlerobots.nl
What is edge to edge?
Content area of the app is drawn between the status bar and navigation bar
What is edge to edge?
Content area of the app is the entire screen, overlapping the status bar and navigation bar
Rainy Days
Lees Simpel
Soosee
Brief history lesson
Android 4.4 Kitkat (2013)
Status and navigation bar translucent
Android 5 Lollipop (2014)
Status and navigation bar colors
Android 9 Pie (2018)
Initial gesture navigation
Android 10 Pie (2019)
Gesture navigation, system bar protection
Why now?
Note:
Going edge to edge
Enable edge to edge
enableEdgeToEdge()
enableEdgeToEdge()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
// compose stuff
}
}
enableEdgeToEdge()
Specify SystemBarStyle
fun ComponentActivity.enableEdgeToEdge(
statusBarStyle: SystemBarStyle = SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT),
navigationBarStyle: SystemBarStyle = SystemBarStyle.auto(DefaultLightScrim, DefaultDarkScrim)
)
SystemBarStyle.auto()
SystemBarStyle.light/dark()
My recommendation
enableEdgeToEdge()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge(
statusBarStyle = SystemBarStyle.auto(0, 0, { /* dark */ true }),
navigationBarStyle = SystemBarStyle.auto(0, 0, { /* dark */ true })
)
setContent {
// compose stuff
}
}
Handle visual overlap
Window insets
Common insets
Lesser used
Combined insets
Applying insets (views)
Applying insets (views)
ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
// Apply the insets as a margin to the view. This solution sets
// only the bottom, left, and right dimensions, but you can apply whichever
// insets are appropriate to your layout. You can also update the view padding
// if that's more appropriate.
v.updateLayoutParams<ViewGroup.MarginLayoutParams> {
leftMargin = insets.left
bottomMargin = insets.bottom
rightMargin = insets.right
}
// Return CONSUMED if you don't want want the window insets to keep passing
// down to descendant views.
WindowInsetsCompat.CONSUMED
}
Applying insets (views)
Tips & tricks
Window insets in Compose
Window insets in Compose
Demo
Tips & tricks
Default insets handling
Scaffold
Scaffold(topBar = {
// applies top + horizontal systembars padding
TopAppBar({ Text("My App") })
}) { innerPadding ->
// innerPadding contains inset information for you to use and apply
LazyColumn(
// consume insets as scaffold doesn't do it by default (optional)
modifier = Modifier.consumeWindowInsets(innerPadding),
contentPadding = innerPadding
) {
// ..
}
}
LazyColumn
LazyColumn
LazyColumn(
Modifier.imePadding()
) {
// Other content
item {
Spacer(
Modifier.windowInsetsBottomHeight(
WindowInsets.systemBars
)
)
}
}
Testing
Demo
Resources
Q&A