Me cuesta entender el concepto de fitsSystemWindows
que, dependiendo de la vista, hace cosas diferentes. Según la documentación oficial es un
Atributo interno booleano para ajustar el diseño de la vista en función de las ventanas del sistema, como la barra de estado. Si es verdadero, ajusta el relleno de esta vista para dejar espacio para las ventanas del sistema .
Ahora, comprobando la View.java
clase, puedo ver que cuando se establece en true
, las inserciones de la ventana (barra de estado, barra de navegación ...) se aplican a los rellenos de vista, lo que funciona de acuerdo con la documentación citada anteriormente. Esta es la parte relevante del código:
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;
}
Con el nuevo diseño de Material hay nuevas clases que hacen un uso extensivo de esta bandera y aquí es donde surge la confusión. En muchas fuentes fitsSystemWindows
se menciona como la bandera para establecer la vista detrás de las barras del sistema. Ver aquí .
La documentación en ViewCompat.java
para setFitsSystemWindows
dice:
Establece si esta vista debe o no tener en cuenta las decoraciones de la pantalla del sistema, como la barra de estado e insertar su contenido; es decir, controlar si se ejecutará la implementación predeterminada de {@link View # fitSystemWindows (Rect)}. Vea ese método para más detalles .
De acuerdo con esto, ¿ fitsSystemWindows
simplemente significa que la función fitsSystemWindows()
se ejecutará? Las nuevas clases de Material parecen usar esto para dibujar debajo de la barra de estado. Si miramos DrawerLayout.java
el código, podemos ver esto:
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);
}
}
Y vemos el mismo patrón en el nuevo CoordinatorLayout
o AppBarLayout
.
¿No funciona esto exactamente de la manera opuesta a la documentación fitsSystemWindows
? En los últimos casos, significa dibujar detrás de las barras del sistema .
Sin embargo, si desea FrameLayout
que se dibuje detrás de la barra de estado, establecerlo fitsSystemWindows
en verdadero no funciona, ya que la implementación predeterminada hace lo que se documenta inicialmente. Debe anularlo y agregar los mismos indicadores que las otras clases mencionadas. ¿Me estoy perdiendo de algo?
CoordinatorLayout
, usan esa bandera para inferir si deberían pintar detrás de la barra de estado o no. Ese no es el caso FrameLayout
, por ejemplo.