CoordinatorLayout not drawing behind status bar even with windowTranslucentStatus and fitsSystemWindows
B

4

27

I am trying to draw views behind the status bar like this: Desired result

I tried to produce this effect with the recommended techniques, but I get this:

Actual result

It's clear from the screenshot that none of my app content is being drawn behind the status bar.

What's interesting is that somehow, the Nav Drawer manages to draw behind the status bar:

enter image description here

Stuff I did:

  • Use support library widgets - CoordinatorLayout, AppBarLayout, Toolbar, DrawerLayout
  • windowTranslucentStatus set to true in my app theme
  • fitsSystemWindows set to true on my CoordinatorLayout

This is my app theme:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  <!-- Customize your theme here. -->
  <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@android:color/transparent</item>
    <item name="colorAccent">@color/colorAccent</item>

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

This is my activity layout:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <FrameLayout android:id="@+id/page_container"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:fitsSystemWindows="true"/>

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</android.support.v4.widget.DrawerLayout>

The FrameLayout in my activity layout is replaced with this fragment layout:

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

    <FrameLayout android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:paddingLeft="@dimen/activity_horizontal_margin"
                 android:paddingRight="@dimen/activity_horizontal_margin"
                 android:paddingTop="@dimen/activity_vertical_margin"
                 android:paddingBottom="@dimen/activity_vertical_margin"
                 android:background="@android:color/holo_blue_bright"
                 tools:context=".MainActivity">

        <TextView android:text="@string/lorem_ipsum"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content" />
    </FrameLayout>

    <android.support.design.widget.AppBarLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        app:elevation="0dp"
        android:theme="@style/AppTheme.TransparentAppBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@android:color/transparent"
            app:title="@string/hello_blank_fragment"
            app:popupTheme="@style/AppTheme.OverflowMenu" />

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

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>
Blurb answered 12/11, 2015 at 9:57 Comment(4)
Try setting fitsSystemWindows="false" on the drawer layout.Beatty
@mvai I just tried it and it doesn't seem to change anythingBlurb
I had a similar issue, try this: #34762171Abampere
see this answer: https://mcmap.net/q/137223/-translucent-transparent-status-bar-coordinatorlayout-toolbar-fragmentOdoriferous
R
31

edit for future readers: there's a lot of good information on the subject and the issue on the comments too, make sure to read through them.

original answer: Your theme is wrong, that's why. Unfortunately, there're differences on how to activate in in Kitkat or Lollipop. On my code I did it in Java, but you can also achieve it in XML if you want to play with the V21 folders on your resources tree. The name of the parameters will be very similar to the Java counterparts.

Delete the android:windowTranslucentStatus from your XML and in Java use like that:

   public static void setTranslucentStatusBar(Window window) {
      if (window == null) return;
      int sdkInt = Build.VERSION.SDK_INT;
      if (sdkInt >= Build.VERSION_CODES.LOLLIPOP) {
         setTranslucentStatusBarLollipop(window);
      } else if (sdkInt >= Build.VERSION_CODES.KITKAT) {
         setTranslucentStatusBarKiKat(window);
      }
   }

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
   private static void setTranslucentStatusBarLollipop(Window window) {
      window.setStatusBarColor(
             window.getContext()
                   .getResources()
                   .getColor(R.color. / add here your translucent color code /));
   }

   @TargetApi(Build.VERSION_CODES.KITKAT)
   private static void setTranslucentStatusBarKiKat(Window window) {
      window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
   }

then you can call from your activity setTranslucentStatusBar(getWindow());

edit:

making the status bar translucent and drawing behind it (for some reason I cannot understand) are two separate tasks in Android.

I've looked more on my code and I'm for sure have A LOT more android:fitsSystemWindows="true" on my layout than just the CoordinatorLayout.

below are all the Views on my layout with android:fitsSystemWindows="true" on them:

  • CoordinatorLayout
  • AppBarLayout
  • CollapsingToolbarLayout
  • ImageView (with the background image)
  • FrameLayout (with the content of the header)

so my suggestion is to just test/try filling up android:fitsSystemWindows="true" on your XML.

Regelation answered 12/11, 2015 at 10:27 Comment(11)
Your technique removes the dark tint background of the status bar, but it does still does not let my CoordinatorLayout fill the area behind the status bar. Now it looks like this: i.imgur.com/koMgcm0.png?1Blurb
Sorry to say applying fitsSystemWindows to everything didn't work. I even tried adding a CollapsingToolbarLayout with an ImageView to my fragment layout with fitsSystemWindows, but that didn't work either. Seriously, thanks for your help though. I think I'll have to try some unorthodox solutions.Blurb
I'm pretty sure it works with just my Java and some fitSystemWindows. I'm looking your layouts, I guess you would have to remove from your activity layout. I mean, remove from the DrawerLayout, NavigationView and FrameLayout. I guess u only add true to the stuff that should not be behind it (for example you have a "title" view) but the stuff that should be behind it should not have fitSystemWindowsRegelation
The DrawerLayout and NavigationView need fitsSystemWindows because they are supposed to be drawn behind the status bar too (as per the Material Design spec). The FrameLayout actually contains my content (it is replaced by fragment layout) so it needs fitsSystemWindows too. I'm beginning to think it's not working because I am using fragments...Blurb
My project is with fragments too, that's not the reason. I guess you're misinterpreting the fitSystemWindows developer.android.com/reference/android/view/… . Give it a try.Regelation
I got it to work! You were right, I was misunderstanding fitsSystemWindows. It doesn't expand a view to "fit the system window", it actually requests that the view avoid window decorations like the status bar. I fixed the problem by removing fitsSystemWindows from everything. Setting windowsTranslucentStatus to true in my app theme is sufficient to achieve my desired effect; fitsSystemWindows actually interferes with that.Blurb
I'm going to accept your answer as the accepted answer. I think it would be helpful though if you edit your answer to include a summary of my explanation or ask readers to look at the comments.Blurb
Can you add the corresponding properties that you need to put in the xml to achieve this through xml instead of java?Generation
I'm not gonna go check the documentation for you. The link is here: developer.android.com/reference/android/view/Window.html you can check. It will be something like window:statusBarColor and window:flagsRegelation
thanks ! btw if you give fitsystemwindows = true for co ordinator layout and make the toolbar scroll up by giving your viewpager appbar_scrolling_view_behavior, then if the statusbarcolor is transparent the toolbar will go behind the status bar, but since status bar is transparent the toolbar will be visible under the status bar, so you need to give the fitssystemwindows=true property to a parent of the co ordinator layoutGeneration
@Generation kindly can you tell how to cope with this scenario DrawerLayout --> Cordinator ->AppBar ->ToolBar , LP and MM it works fine but with Translucent property on for KK then toolbar goes under it and adding padding results toolbar going under appbar and appbar is fixed, i tried fsw on several combinations not worked, i have to use fitsystems windows on Main drawer so that it doesn't show tinted SB when drawer is opened, suggest plz..Armbruster
M
1

This was really confusing for me but I eventually figured it out for my combination of views which looks like this:

<android.support.v4.widget.SwipeRefreshLayout - **no fitsSystemWindow set**

<android.support.design.widget.CoordinatorLayout- android:fitsSystemWindows="true"

<android.support.design.widget.AppBarLayout - android:fitsSystemWindows="true"

<android.support.design.widget.CollapsingToolbarLayout - android:fitsSystemWindows="true"

<RelativeLayout - android:fitsSystemWindows="true"

<ImageView - android:fitsSystemWindows="true"

I also used the methods posted by Budius in my app to get the transparent status bar working:

Delete the android:windowTranslucentStatus from your XML and in Java use like that:

   public static void setTranslucentStatusBar(Window window) {
      if (window == null) return;
      int sdkInt = Build.VERSION.SDK_INT;
      if (sdkInt >= Build.VERSION_CODES.LOLLIPOP) {
         setTranslucentStatusBarLollipop(window);
      } else if (sdkInt >= Build.VERSION_CODES.KITKAT) {
         setTranslucentStatusBarKiKat(window);
      }
   }

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
   private static void setTranslucentStatusBarLollipop(Window window) {
      window.setStatusBarColor(
             window.getContext()
                   .getResources()
                   .getColor(R.color. / add here your translucent color code /));
   }

   @TargetApi(Build.VERSION_CODES.KITKAT)
   private static void setTranslucentStatusBarKiKat(Window window) {
      window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
   }
Magill answered 23/10, 2016 at 9:11 Comment(1)
You helped me a little on my problem hence +1Complimentary
O
1
  1. If I want to draw behind StatusBar I use CoordinatorLayout as most parent view of Activity (android:fitsSystemWindows="false")

styles.xml(v21)

<style name="MyTheme.NoActionBar.TransparentStatusBar">
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:windowTranslucentStatus">true</item>
    </style>

Then If you want to change statubarcolor, you have to remove TRANSLUENT_FLAG like this

Window window = activity().getWindow();
        if(showTransluent){
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(Color.TRANSPARENT);
        }else {
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(ContextCompat.getColor(activity(), R.color.colorPrimaryDark));
        }
  1. If I want StatusBar to be transluent and simultanieousy kepping view away from hidding behind StatusBar I use as most parent view FrameLayout with argument

My styles.xml(v21) look like

<resources>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    </style>

    <style name="AppTheme.NoStatusBar" parent="AppTheme.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
        <item name="windowActionBarOverlay">true</item>
        <item name="android:windowActionBarOverlay">true</item>
    </style>
</resources>

And styles.xml

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

Maybe the point key here is to be sure that you use AppCompactActivity as well as you use Theme.AppCompact as root for your styles.

Overmodest answered 25/11, 2016 at 19:48 Comment(0)
H
1

Add this

android:fitsSystemWindows="true"

in the inner views of the AppBarLayout, it solved the issue for me

Henrietta answered 1/8, 2020 at 19:28 Comment(1)
Thanks. Same here..Complimentary

© 2022 - 2024 — McMap. All rights reserved.