Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CoordinatorLayout not drawing behind status bar even with windowTranslucentStatus and fitsSystemWindows

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> 
like image 658
Joshua Avatar asked Nov 12 '15 09:11

Joshua


People also ask

How do I show content behind the status bar?

You can show app content behind the status bar using SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN You should also use SYSTEM_UI_FLAG_LAYOUT_STABLE to help your app maintain stable layout.

How do I use CoordinatorLayout?

By specifying Behaviors for child views of a CoordinatorLayout you can provide many different interactions within a single parent and those views can also interact with one another. View classes can specify a default behavior when used as a child of a CoordinatorLayout by implementing the AttachedBehavior interface.

What does fitsSystemWindows do?

fitsSystemWindows = true sets the padding to your view (if needed) to prevent your content from being obscured by the system status bar or navigation bar.

What is CoordinatorLayout?

Android CoordinatorLayout is a super-powered FrameLayout. It has a lot more to offer than it seems. It has additional level of control over it's child views. It coordinates the animations and transitions of child views with one another.


2 Answers

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.

like image 142
Budius Avatar answered Sep 28 '22 07:09

Budius


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);    } 
like image 29
Simon Avatar answered Sep 28 '22 08:09

Simon