androidxmlandroid-styles

Unexpected behaviour of "android:windowTranslucentNavigation"


I have first encountered this strange behaviour in my main app which is currently in development. In order to debug the issue i created a test app. The test app has only one activity MainActivity which extends Activity. The theme for this activity is AppTheme.NoActionBar declared in styles.xml

    <style name="AppTheme">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="AppTheme.NoActionBar" parent="AppTheme.Base">
        <item name="android:statusBarColor">#FFFFFF</item>
        <item name="android:windowTranslucentNavigation">true</item>
    </style>

    <style name="AppTheme.Base" parent="Theme.MaterialComponents.Light.NoActionBar">
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
    </style>

With this the output looks like this Image 1Image 1 Now that's not what i expected,look how the status bar and toolbar are merged together.

But when i removed this line of code

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

This is what i ended up with Image 2 Notice this time the toolbar and status bar are not merged, instead we have the status bar in place and the toolbar below it. I am unable to understand how in Image 1 the layout is getting drawn under the status bar

I know the question will confuse a lot of you reading this. But how can adding a attribute

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

which has nothing to do with status bar is effecting it.

My test device is running on android Pie


Solution

  • Okay so after a bit of research i found that

    android:windowTranslucentNavigation=true
    

    not only makes the navigation bar translucent, but it also allows the layout to draw draw behind the status bar.

    The problem is that if we want to have a colored navigation bar (for Lollipop and higher) instead of translucent, we need to remove that line and by doing so we won't be able to draw behind the status bar anymore.

    Workaround:

    Declare styles.xml(v21) and set the navigation bar color

    <item name="android:navigationBarColor">@color/red</item>
    

    Now since this styles.xml file will be used only for devices with API >= 21 we need to make sure that the layout is also drawn behind the status bar for API >= 21 so,add the following lines in your activity's onCreate before setContentView

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) // Checks the API level of the device
    {
        getWindow()
                  .getDecorView();
                  .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | 
                                         View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    }
    

    Conclusion: For devices (API < 21) android:windowTranslucentNavigation=true will make the navigation bar translucent and the layout will be drawn behind the status bar and for devices (API >= 21) we can modify the color of the navigation bar without breaking the UI