Я пытаюсь понять концепцию 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
? В последних случаях это означает рисовать позади системных баров.
Однако, если вы хотите, чтобы FrameLayout
рисовал себя за строкой состояния, установка fitsSystemWindows
в значение true не делает трюк, поскольку реализация по умолчанию делает то, что задокументировано на начальном этапе. Вы должны переопределить его и добавить те же флаги, что и другие упомянутые классы. Я что-то пропустил?