1 year ago

#46821

test-img

Pasha Oleynik

Replacement deprecated window.decorView.systemUiVisibility with WindowInsetsController

I have an Activity with container for fragments. Also, I have three fragment FragmentA, FragmentB, FragmentC.

When I navigate to FragmentC I want the translucent status bar to overlap the content. In all other cases I want to use default appearance, when all the content is under status bar (without overlap). For this purposes I modified my AppTheme to this:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:windowBackground">@android:color/white</item>
    <item name="android:statusBarColor">@color/transparent</item>

    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">false</item>
</style>

Also, I have implemented such util to dynamically change "modes" of appearance:

data class WindowSettings(
    val fitSystemWindowsForStatusBar: Boolean
)

private fun BaseFragment.windowSettingsForFragment(): WindowSettings {
    return when (this) {
        is FragmentC -> WindowSettings(fitSystemWindowsForStatusBar = false)
        else -> WindowSettings(fitSystemWindowsForStatusBar = true)
    }
}

private fun BaseFragment.applyWindowSettings(settings: WindowSettings) {
    if (settings.fitSystemWindowsForStatusBar) {
        @Suppress("Deprecation")
        requireActivity().window.decorView.systemUiVisibility =
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    } else {
        @Suppress("Deprecation")
        requireActivity().window.decorView.systemUiVisibility =
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    }
}

fun BaseFragment.retrieveWindowSettings(): () -> Unit {
    return {
        applyWindowSettings(windowSettingsForFragment())
    }
}

And in onResume of my BaseFragment I use this to change "mode":

override fun onResume() {
        super.onResume()
        retrieveWindowSettings().invoke()
}

And it works well, but I want to avoid using deprecated features. I know, that replacement for deprecated window.decorView.systemUiVisibility is to use WindowInsetsController. But I can not figure out how to use it for my purposes, because I only found a solution for hiding status bar, like this:

WindowInsetsControllerCompat(window, mainContainer).let { controller ->
        controller.hide(WindowInsetsCompat.Type.systemBars())
        controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}

So, my question is what alternative of making systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN?

android

android-statusbar

windowinsets

0 Answers

Your Answer

Accepted video resources