Я изо всех сил пытаюсь понять концепцию, fitsSystemWindowsпоскольку в зависимости от точки зрения он делает разные вещи. Согласно официальной документации это
Логический внутренний атрибут для настройки макета представления на основе системных окон, таких как строка состояния. Если true, регулирует отступ этого представления, чтобы оставить место для системных окон .
Теперь, проверяя View.javaкласс, я вижу, что при установке trueна вставки окна (строка состояния, панель навигации ...) применяются к отступам представления, что работает в соответствии с документацией, приведенной выше. Это соответствующая часть кода:
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;
}
В новом дизайне материалов появились новые классы, которые широко используют этот флаг, и здесь возникает путаница. Во многих источниках fitsSystemWindowsупоминается как флаг, который нужно установить, чтобы скрыть представление за системными панелями. Смотрите здесь .
В документации ViewCompat.javaдля setFitsSystemWindowsговорится:
Устанавливает, должно ли это представление учитывать художественные оформления системного экрана, такие как строка состояния, и вставлять ее содержимое; то есть контроль того, будет ли выполняться реализация по умолчанию для {@link View # fitSystemWindows (Rect)}. См. Этот метод для получения более подробной информации .
По этому fitsSystemWindowsпросто означает, что функция fitsSystemWindows()будет выполнена? Новые классы материалов, кажется, используют это просто для рисования под строкой состояния. Если мы посмотрим на DrawerLayout.javaкод пользователя, то увидим следующее:
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);
}
}
И мы видим тот же образец в новом CoordinatorLayoutили AppBarLayout.
Разве это не работает прямо противоположно документации fitsSystemWindows? В последних случаях это означает рисование за решеткой системы .
Однако, если вы хотите, чтобы a FrameLayoutотображался за строкой состояния, установка значения fitsSystemWindowstrue не поможет, поскольку реализация по умолчанию выполняет то, что задокументировано изначально. Вы должны переопределить его и добавить те же флаги, что и другие упомянутые классы. Я что-то упускаю?
CoordinatorLayout, используют этот флаг, чтобы определить, должны ли они рисовать за строкой состояния или нет. Это FrameLayout, например, не так.