utahwithak
utahwithak

Reputation: 6325

Extend view under status bar on Android 11

We've been trying to migrate our codebase to compile (without using deprecations) against API 30 and have ran into some issues with the broad deprecations dealing with the system UI and window insets.

We're trying to have content drawn under a persistent status bar, but not under the nav bar. (so setDecorFitsSystemWindows doesn't work)

Previously we were doing this:


activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
activity?.window?.decorView?.systemUiVisibility?.let {
    activity?.window?.decorView?.systemUiVisibility = it and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
}

binding.start.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)

I've been able to get the status bar consistently turned light via

window.insetsController?.setSystemBarsAppearance(0, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS)

Using insets the controller, but I can't figure out how to get the view to extend up under the status bar.

I tried messing with the insets but setOnApplyWindowInsetsListener isn't called anymore for their modifications.

Looking all over the web I don't see any non-deprecated way to get this behavior. I'm wondering if this is even possible anymore?

Upvotes: 0

Views: 1972

Answers (2)

utahwithak
utahwithak

Reputation: 6325

I stumbled upon this resource about Android 11 insets and was able get this working: https://blog.stylingandroid.com/android11-windowinsets-part1/

The final compat version to get my desired look is this:

        // force view to be full screen and appearance to be light
        //
        activity?.window?.let { window ->
            WindowCompat.setDecorFitsSystemWindows(window, false)
            window.statusBarColor = Color.TRANSPARENT
            val controller = WindowInsetsControllerCompat(window, binding.root)
            controller.isAppearanceLightNavigationBars = false
        }
        // Adjust view to be under status bar
        //
        binding.root.setOnApplyWindowInsetsListener { view, windowInsets ->
            val insetsCompat = WindowInsetsCompat.toWindowInsetsCompat(windowInsets, view)
            val insets = insetsCompat.getInsets(WindowInsetsCompat.Type.navigationBars())
            binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
                updateMargins(insets.left, insets.top, insets.right, insets.bottom)
            }
            WindowInsetsCompat.Builder()
                .setInsets(WindowInsetsCompat.Type.navigationBars(), insets)
                .build().toWindowInsets() ?: windowInsets
        }


The important bits I learned was that if you setDecorFitsSystemWindows to false then the onApplyWindowInsets will be called which allows you to custom inset your view however you'd like.

This is working and giving the same (correct) results from our min of api 26 to 30.

Upvotes: 1

Rohaitas Tanoli
Rohaitas Tanoli

Reputation: 807

In style

<item name="android:windowTranslucentStatus">true</item>

In Manifest

android:fitsSystemWindows="true"

enter image description here

In my Android 11, The status bar icon color also changes light and dark while scrolling.

Upvotes: 1

Related Questions