Transparent status bar not working with windowTranslucentNavigation="false"
Asked Answered
W

5

40

I am developing an Activity where I need to make the navigation bar opaque, and the status bar transparent on devices running 5.0+ (API 21+). The styles I am using are below, along with an explanation of my problem.

AppTheme extends Theme.AppCompat.Light.NoActionBar

<item name="android:statusBarColor">@color/transparent</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/welbe_red_transparent</item>

FullscreenTheme extends AppTheme

<item name="android:windowNoTitle">true</item>
<item name="android:statusBarColor">@color/transparent</item>
<item name="android:windowTranslucentNavigation">true</item>

This makes the app look like this

android:windowTranslucentNavigation="true"

If I remove the android:windowTranslucentNavigation style, or set it to false in Fullscreen, it fixes the navigation bar issue. The problem is the status bar turns completely white instead of staying transparent and displaying the content behind it.

android:windowTranslucentNavigation="false"

I have tried using fitsSystemWindow="true" in my layouts, but it didn't fix the issue. Anyone know why this is happening?

Watchdog answered 3/2, 2015 at 0:41 Comment(2)
I'm a bit unclear as to what you really want: navigation bar default, transparent status bar and your background behind the status bar. Correct?Hipped
Yes, that is exactly what I want to display. The background stops extending behind the status bar when I turn off android:windowTranslucentNavigation.Watchdog
H
74

android:windowTranslucentNavigation does one thing that android:statusBarColor doesn't do, which is requesting the SYSTEM_UI_FLAG_LAYOUT_STABLE and SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN flags.

These are the ones that you need to request in order to draw behind the status bar.

Request them in the onCreate of your Activity:

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

Alternatively you can also simply set your apps theme background and that will also pop up behind your status bar.

More information here.

Hipped answered 18/2, 2015 at 21:43 Comment(2)
Exactly what I needed! Thank you. The docs say "adjust the window flags as required", but fail to mention which flags...Watchdog
After lot of search and hours of efforts, I finally found the answer here. Many many thanks. As an additional note, we should remove fitsSystemWindows for this to work correct.Kramatorsk
P
6

As far as I know there's no proper way to set the color of the status bar on APIs lower than 19.

For API 19+ you can use a similar attribute to windowTranslucentNavigation only for the status bar:

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

Notes:

  • The reason you were getting a white status bar is because of

    <item name="android:statusBarColor">@color/transparent</item> 
    
  • There are some hacks that work on specific manufacturer devices, but I wouldn't use them myself.

Portuna answered 13/2, 2015 at 19:14 Comment(8)
I understand how to accomplish this in a backwards compatible manner, I am using different styles on 19+ and 21+. The background should be under the transparent status bar on 21+, but the combination of settings I am using with AppCompat is breaking that feature somewhere. This answer doesn't actually answer the question.Watchdog
@AustynMahoney "I need to make the navigation bar opaque, while keeping the status bar transparent on 5.0+" - done. "I also need this to work on minSdkVersion 14+" - won't work, 19+ only. What is your question then?Portuna
The question is still the same. Why does turning off android:windowTranslucentNavigation stop the background from fitting the system window fully (the reason why the status bar is white). I do not need the transparency to work on 14+ (I know its not possible), I just point out that the solution needs to use AppCompat themes/styles to maintain backward compatibility.Watchdog
@AustynMahoney well I did say that the statusBar is white because you're setting a transparent color, have you tried removing that?Portuna
I'm not sure you understand what I am trying to do here if you suggest removing the transparent color. "You can also draw behind the status bar yourself. For example, if you want to show the status bar transparently over a photo, with a subtle dark gradient to ensure the white status icons are visible. To do so, set the android:statusBarColor attribute to @android:color/transparent and adjust the window flags as required." - developer.android.com/training/material/theme.htmlWatchdog
I am probably missing the noted, but never explained "adjust the window flags" part.Watchdog
@AustynMahoney the link you posted, is for Material theme. It doesn't mean the AppCompat version. Your question still remains unclear. However using AppCompat with the attribute I provided (windowTranslucentStatus), does make the status bar translucent and content is drawn behind it. At least when running on API 21.Portuna
android:windowTranslucentStatus is a KitKat attribute, not AppCompat (I use it in my 19+ theme). It makes the status bar semi-translucent with a gradient for background protection. The new Material theme attributes let you have a completely transparent status bar. I apologize if this wasn't clear in my question. I have edited to make sure people know I am talking about this working on a 21+ Material Theme, which just happens to be AppCompat in my case.Watchdog
G
2

I struggle with this for over 3 hours. Wrap everything in a CoordinatorLayout it is the only one that seems to pay attention to the fitsSystemWindow="true" or "false"

This is my main activity fragment

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/content_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include layout="@layout/layout_google_map"/>

    <include layout="@layout/layout_toolbar_transparent"/>

    <include layout="@layout/layout_action_buttons"/>

    <include layout="@layout/layout_bottom_sheet"/>

</android.support.design.widget.CoordinatorLayout>

this is my toolbar layout

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.v7.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:theme="@style/ToolbarTheme"
        app:popupTheme="@style/AppTheme.PopupOverlay">

        <android.support.v7.widget.AppCompatImageView
            android:layout_width="wrap_content"
            android:layout_height="?actionBarSize"
            android:layout_centerHorizontal="true"
            android:layout_gravity="center"
            android:adjustViewBounds="true"
            app:srcCompat="@drawable/ic_fynd_logo_red"/>

    </android.support.v7.widget.Toolbar>
</android.support.design.widget.CoordinatorLayout>

as you can see, my fragment layout makes the google map be drawn under the status bar.

I have an action bar where the company's logo goes.

And other ui buttons "layout_action_buttons" also wrapped in a Coordinator layout , so the fitsSystemsWindows works.

Check it out.

enter image description here

Guenther answered 8/12, 2016 at 20:28 Comment(6)
Can You show how look compass button on google maps? Because for me is always under top statusbar, and I have problem with move google maps buttonsBohun
You can add padding to your google map. Use this, mMap.setPadding(10, 20, 10, 10); That's how you avoid your map components go under the bar.Guenther
@Bohun also check the accepted answer too, having those flags on your activity will do the trick of drawing under the status bar, and even later change the color of the status bar.Guenther
I used defautl example project from Android studio 'Navigation dreawer activity'. I have 'android.support.v4.widget.DrawerLayout' and inside 'fragment' with google maps. I can't add padding to fragment. Any sugestions? :-)Bohun
@Bohun check this out.. developers.google.com/maps/documentation/android-api/…Guenther
@PedroVarela Your screenshot is showing a weird shadow on top (that grey colored). How can you remove that ?Blackleg
F
0

enter image description here

To achieve this in any activity

  1. Add the style:
 <style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
                <item name="colorPrimary">@color/colorPrimary</item>
                <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
                <item name="colorAccent">@color/colorAccent</item>
                <item name="android:statusBarColor">@android:color/transparent</item>
                <item name="android:windowBackground">@android:color/white</item>
            </style>
  1. Use CoordinatorLayout as root layout in XML

  2. In oncreate() method, before setcontentview use

    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

Fibre answered 12/7, 2019 at 6:6 Comment(1)
I want status bar only transparent but navigation should be default. in my case immersive mode full screen and transparent navigation ovelay on itBerenice
I
0

For the latest android version R and backward compatibility, this works for me.

WindowCompat.getInsetsController(window, window.decorView)?.isAppearanceLightStatusBars =false /* true for dark icon on StatusBar and false for white icon on StatusBar */
WindowCompat.setDecorFitsSystemWindows(window, false)
WindowCompat.getInsetsController(window, window.decorView)?.show(WindowInsetsCompat.Type.statusBars())
ViewCompat.setOnApplyWindowInsetsListener(findViewById(android.R.id.content)) { rootView, insets ->
    val navigationBarHeight = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom
    rootView.setPadding(0, 0, 0, navigationBarHeight)
    insets
}

For Fragment, you can use activity?.window...

Ironing answered 28/5, 2021 at 6:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.