Estou lutando para entender o conceito de fitsSystemWindowsque, dependendo da visão, ele faz coisas diferentes. De acordo com a documentação oficial, é uma
Atributo interno booleano para ajustar o layout da vista com base nas janelas do sistema, como a barra de status. Se verdadeiro, ajusta o preenchimento dessa visualização para deixar espaço para as janelas do sistema .
Agora, verificando a View.javaclasse, vejo que, quando definido como true, as inserções da janela (barra de status, barra de navegação ...) são aplicadas aos campos de visualização, que funcionam de acordo com a documentação citada acima. Esta é a parte relevante do 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;
}
Com o novo design de material, há novas classes que fazem uso extensivo dessa bandeira e é aí que entra a confusão. Em muitas fontes, fitsSystemWindowsé mencionado como o sinalizador a ser definido para colocar a visualização atrás das barras do sistema. Veja aqui .
A documentação em ViewCompat.javafor setFitsSystemWindowsdiz:
Define se essa visualização deve ou não levar em conta as decorações da tela do sistema, como a barra de status, e inserir seu conteúdo; isto é, controlar se a implementação padrão do {@link View # fitSystemWindows (Rect)} será executada. Veja esse método para mais detalhes .
De acordo com isso, fitsSystemWindowssignifica simplesmente que a função fitsSystemWindows()será executada? As novas classes de materiais parecem usar isso apenas para desenhar na barra de status. Se olharmos para DrawerLayout.javao código, podemos ver o seguinte:
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);
}
}
E vemos o mesmo padrão no novo CoordinatorLayoutou AppBarLayout.
Isso não funciona exatamente da maneira oposta à documentação fitsSystemWindows? Nos últimos casos, significa desenhar atrás das barras do sistema .
No entanto, se você quiser FrameLayoutse destacar atrás da barra de status, definir fitsSystemWindowscomo true não funciona, como a implementação padrão faz o que está documentado inicialmente. Você deve substituí-lo e adicionar os mesmos sinalizadores que as outras classes mencionadas. Estou esquecendo de algo?
CoordinatorLayout, usam esse sinalizador para inferir se devem pintar atrás da barra de status ou não. Não é esse o caso FrameLayout, por exemplo.