11

I'm currently working on an app for which I want to enable a transparent status bar. I want an ImageView (which I require for its scaleType attribute) to cover the entirety of the screen so that the image will show below the status bar. Here's my layout:

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:fitsSystemWindows="true"
            android:scaleType="centerCrop"
            android:src="@drawable/picture" />

        <android.support.v7.widget.Toolbar
            (...toolbar stuff...)
        />

        (...some other stuff...)

    </RelativeLayout>

    <include layout="@layout/drawer" />
</android.support.v4.widget.DrawerLayout>

As you can see, it's a regular DrawerLayout. Notice that the DrawerLayout, the RelativeLayout and the ImageView all have the fitsSystemWindows attribute set to true.

My problem is: If I set a background resource (like a color or a picture) to either the DrawerLayout or the RelativeLayout in the above code, I can see that color or picture "below" the status bar, exactly as I want it, but the ImageView's 'src' drawable is always shown under it, as if it ignored the fitsSystemWindows attribute completely.

I have the following attributes in my theme:

<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/primary_dark</item>

With primary_dark being a semitransparent black (this shouldn't matter anyway, since as I said, this seems to be an issue exclusive to my ImageView. The transparent status bar works perfect for either the DrawerLayout or the RelativeLayout.

Willis
  • 5,308
  • 3
  • 32
  • 61
Sergio Morales
  • 2,600
  • 6
  • 32
  • 40

5 Answers5

2

This works perfectly for me

You have android:fitsSystemWindows="true"in every viewGroup params. Try to left only one in ImageView.

Or completely remove all of them.

1
fitSystemWindows

does not work in RelativeLayout. Use a FrameLayout or a ViewGroup extending FrameLayout

Julian Os
  • 281
  • 1
  • 15
1

ImageView extends View and does not override it's method onApplyWindowInsets. Default logic defined in View is described in docs:

By default if a view's {@link #setFitsSystemWindows(boolean) fitsSystemWindows} * property is set then the view will consume the system window insets and apply them * as padding for the view.

And the same logic applies to RelativeLayout, so i'd recommend you to add the following line to your Activity/Fragment code to skip applying insets:

ViewCompat.setOnApplyWindowInsetsListener(relativeLayout) { _, insets -> insets }

As a result, the top padding will be gone. Transparent status bar color is also required to be set in order to see your view beneath it:

<item name="android:statusBarColor">@android:color/transparent</item>
0

fitSystemWindows doesn't expand a view to "fit the system window", it rather gives view a chance to handle it in desired way. And by default ImageView doesn't take this offer, in contrast to DrawerLayout or CoordinatorLayout. You need to teach ImageView to use system window area. Try to add something like that in your onCreate() method:

imageView.setOnApplyWindowInsetsListener((view, windowInsets) -> {
    view.setPaddingRelative(
            view.getPaddingStart(),
            windowInsets.getStableInsetTop(),
            view.getPaddingEnd(),
            view.getPaddingBottom()
    );
    return windowInsets;
});

You may need to return changed windowInsets object in order to let other views with 'fitsSystemWindows' works properly altogether.

demaksee
  • 1,108
  • 11
  • 16
  • Here I found very good link how to deal with windowInsets: https://stackoverflow.com/a/38929893/755313 – demaksee Jul 02 '18 at 20:30
-1

Because android:fitsSystemWindows="true" will add a padding to the ImageView, so the src is below the status bar. The padding size is the insets (the status bar height ). You can use the FitsSystemWindowsFrameLayout to solve this problem.

Micho
  • 3,929
  • 13
  • 37
  • 40
Xiong
  • 11
  • 1