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?

Austyn Mahoney
  • 11,398
  • 8
  • 64
  • 85
  • 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? – Jeroen Mols Feb 18 '15 at 06:55
  • Yes, that is exactly what I want to display. The background stops extending behind the status bar when I turn off `android:windowTranslucentNavigation`. – Austyn Mahoney Feb 18 '15 at 19:40

5 Answers5

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.

Austyn Mahoney
  • 11,398
  • 8
  • 64
  • 85
Jeroen Mols
  • 3,436
  • 17
  • 24
  • 3
    Exactly what I needed! Thank you. The docs say "adjust the window flags as required", but fail to mention which flags... – Austyn Mahoney Feb 19 '15 at 23:12
  • 2
    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. – Atul Aug 19 '16 at 06:16
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.

Community
  • 1
  • 1
Simas
  • 43,548
  • 10
  • 88
  • 116
  • 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. – Austyn Mahoney Feb 18 '15 at 18:37
  • @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? – Simas Feb 18 '15 at 19:04
  • 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. – Austyn Mahoney Feb 18 '15 at 19:35
  • @AustynMahoney well I did say that the statusBar is white because you're setting a transparent color, have you tried removing that? – Simas Feb 18 '15 at 19:40
  • 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." - https://developer.android.com/training/material/theme.html – Austyn Mahoney Feb 18 '15 at 19:52
  • I am probably missing the noted, but never explained "adjust the window flags" part. – Austyn Mahoney Feb 18 '15 at 19:52
  • @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. – Simas Feb 18 '15 at 20:11
  • `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. – Austyn Mahoney Feb 18 '15 at 23:01
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

Pedro Varela
  • 2,296
  • 1
  • 26
  • 32
  • 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 buttons – Peter Dec 25 '16 at 12:25
  • 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. – Pedro Varela Dec 26 '16 at 17:32
  • @Peter 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. – Pedro Varela Dec 26 '16 at 17:37
  • 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? :-) – Peter Dec 26 '16 at 18:55
  • @Peter check this out.. https://developers.google.com/maps/documentation/android-api/map#map_padding – Pedro Varela Dec 26 '16 at 19:17
  • @PedroVarela Your screenshot is showing a weird shadow on top (that grey colored). How can you remove that ? – Gaurav Arora Jan 17 '18 at 07:07
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

Kishan Solanki
  • 13,761
  • 4
  • 85
  • 82
  • I want status bar only transparent but navigation should be default. in my case immersive mode full screen and transparent navigation ovelay on it – Vasudev Vyas Aug 17 '19 at 05:22
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...

RBK
  • 2,481
  • 2
  • 30
  • 52