I am trying to understand the concept of fitsSystemWindows , because it does different things depending on the type. According to official documentation,
A logical internal attribute for customizing the layout of a view based on system windows, such as a status bar. If true, adjust the layout of this view to leave space for system windows .
Now, checking the View.java class, I see that when set to true window inserts (status bar, navigation bar ...) are applied to view windows that work in accordance with the above documentation. This is an important 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, new classes appear that make wide use of this flag, and this is where confusion arises. In many sources, fitsSystemWindows is referred to as a flag to set to lay the view behind the system bars. See here .
The documentation in ViewCompat.java for setFitsSystemWindows says:
Sets whether this representation should be taken into account when decoding the system screen, for example, in the status bar and insert its contents; , that is, by controlling, the default implementation {@link View # fitSystemWindows (Rect)} will be executed. See this method for details .
Accordingly, fitsSystemWindows simply means that the fitsSystemWindows() function will be executed? The new material classes seem to just use this to draw on the status bar. If we look at the code of DrawerLayout.java , 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 .
Does this work just the opposite of the document for fitsSystemWindows ? In the latter cases, this means drawing behind the system bars .
However, if you want FrameLayout draw itself behind the status bar, setting fitsSystemWindows to true does not do the trick, since the default implementation does what is documented initially. You must override it and add the same flags as the other classes mentioned. Did I miss something?