Android 15 suggests to use enableEdgeToEdge()
, but this removes the top offset of the status bar, causing the main content to overlap with it.
What is the best way to preserve the height of the status bar? Just leave it transparent and render contents below it.
This is my attempt, it works but it's a lot of code, is there any simpler way?
// in the MainActivity.onCreate():
enableEdgeToEdge()
// the callback will be invoked repeatedly, use this flag to only set the margin-top once
var offsetAdjusted = false
window.decorView.setOnApplyWindowInsetsListener { _, insets ->
if (!offsetAdjusted) {
offsetAdjusted = true
val top = if(Build.VERSION.SDK_INT > Def.ANDROID_10) // for android > 10
insets.getInsetsIgnoringVisibility(WindowInsets.Type.statusBars()).top
else // for android 10
view.rootWindowInsets.stableInsetTop
// the fragment container, which is a FragmentContainerView
val container = binding.root.findViewById<FragmentContainerView>(R.id.nav_host_fragment_activity_main)
val params = container.layoutParams as ViewGroup.MarginLayoutParams
params.topMargin = top
container.layoutParams = params
}
insets
}
EDIT: Seems like there's a way to opt out of this as well temporarily. Not recommended but it's there
Using the flag windowOptOutEdgeToEdgeEnforcement
which can be true/false
Description can be found here
There are many ways possible to do this
There is a flag called fitsSystemWindows
which can be set to true
in your AndroidManifest.xml
if it's just the status bar ( the one on the top ) you're targeting. See here
Another approach, which is very similar to what you've done is using the setOnApplyWindowInsetsListener
You can also return WindowInsetsCompat.CONSUMED
if you consume it, so that it doesn't trigger the code repeatedly
ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets ->
val bars = insets.getInsets(
WindowInsetsCompat.Type.systemBars()
or WindowInsetsCompat.Type.displayCutout()
)
v.updatePadding(
left = bars.left,
top = bars.top,
right = bars.right,
bottom = bars.bottom,
)
WindowInsetsCompat.CONSUMED
}
You can give the section here a read once as well Hope this helps