Home » Android » android – What exactly does fitsSystemWindows do?

android – What exactly does fitsSystemWindows do?

Posted by: admin March 11, 2020 Leave a comment

Questions:

I’m struggling to understand the concept of fitsSystemWindows as depending on the view it does different things. According to the official documentation it’s a

Boolean internal attribute to adjust view layout based on system windows such as the status bar. If true, adjusts the padding of this view to leave space for the system windows.

Now, checking the View.java class I can see that when set to true, the window insets (status bar, navigation bar…) are applied to the view paddings, which works according to the documentation quoted above. This is the relevant part of the code:

private boolean fitSystemWindowsInt(Rect insets) {
    if ((mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS) {
        mUserPaddingStart = UNDEFINED_PADDING;
        mUserPaddingEnd = UNDEFINED_PADDING;
        Rect localInsets = sThreadLocal.get();
        if (localInsets == null) {
            localInsets = new Rect();
            sThreadLocal.set(localInsets);
        }
        boolean res = computeFitSystemWindows(insets, localInsets);
        mUserPaddingLeftInitial = localInsets.left;
        mUserPaddingRightInitial = localInsets.right;
        internalSetPadding(localInsets.left, localInsets.top,
                localInsets.right, localInsets.bottom);
        return res;
    }
    return false;
}

With the new Material design there are new classes which make extensive use of this flag and this is where the confusion comes. In many sources fitsSystemWindows is mentioned as the flag to set to lay the view behind the system bars. See here.

The documentation in ViewCompat.java for setFitsSystemWindows says:

Sets whether or not this view should account for system screen decorations
such as the status bar and inset its content; that is, controlling whether
the default implementation of {@link View#fitSystemWindows(Rect)} will be
executed. See that method for more details
.

According to this, fitsSystemWindows simply means that the function fitsSystemWindows() will be executed? The new Material classes seem to just use this for drawing under the status bar. If we look at DrawerLayout.java‘s code, we can see this:

if (ViewCompat.getFitsSystemWindows(this)) {
        IMPL.configureApplyInsets(this);
        mStatusBarBackground = IMPL.getDefaultStatusBarBackground(context);
    }

public static void configureApplyInsets(View drawerLayout) {
    if (drawerLayout instanceof DrawerLayoutImpl) {
        drawerLayout.setOnApplyWindowInsetsListener(new InsetsListener());
        drawerLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    }
}

And we see the same pattern in the new CoordinatorLayout or AppBarLayout.

Doesn’t this work in the exact opposite way as the documentation for fitsSystemWindows? In the last cases, it means draw behind the system bars.

However, if you want a FrameLayout to draw itself behind the status bar, setting fitsSystemWindows to true does not do the trick as the default implementation does what’s documented initially. You have to override it and add the same flags as the other mentioned classes. Am I missing something?

How to&Answers:

System windows are the parts of the screen where the system is drawing
either non-interactive (in the case of the status bar) or interactive
(in the case of the navigation bar) content.

Most of the time, your app won’t need to draw under the status bar or
the navigation bar, but if you do: you need to make sure interactive
elements (like buttons) aren’t hidden underneath them. That’s what the
default behavior of the android:fitsSystemWindows=“true” attribute
gives you: it sets the padding of the View to ensure the contents
don’t overlay the system windows.

https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec

Answer:

it does not draw behind the system bar
it kind of stretches behind the bar to tint it with the same colors it has but the views it contains is padded inside the status bar
if that makes sense