Що саме робить fitSystemWindows?


126

Я намагаюся зрозуміти поняття fitsSystemWindowsяк залежне від погляду, воно робить різні речі. Згідно з офіційною документацією, це

Буловий внутрішній атрибут для налаштування макета перегляду на основі системних вікон, таких як рядок стану. Якщо це правда, коригує прокладку цього виду, щоб залишати місце для вікон системи .

Тепер, перевіряючи 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 не робитиме хитрощів, оскільки реалізація за замовчуванням робить те, що було задокументовано спочатку. Ви повинні її замінити та додати ті самі прапори, що й інші згадані класи. Я щось пропускаю?


1
Це здається помилкою, я опублікував звіт про помилку на трекері проблем Android
Тім Рай

1
Перевірте тут: medium.com/google-developers/…
Fatih S.

Дякую за посилання, дуже корисно. Все-таки це підтверджує, що там є суперечності. На пов’язаній сторінці написано, що деякі нові віджети, наприклад CoordinatorLayout, використовують цей прапор, щоб зробити висновок про те, чи слід фарбувати їх за рядком стану чи ні. Це не той випадок з FrameLayout, наприклад.
Pin

2
Це було таке чудове запитання та дуже приємна робота, вивчаючи вихідний код Android. Я особливо вдячний, що ви визначили, як нові класи MD по-різному обробляють fitsSystemWindows .... Я божеволіла, намагаючись зрозуміти це!
coolDude

Відповіді:


19

Вікна системи - це частини екрану, де система малює або інтерактивний (у випадку рядка стану), або інтерактивний (у випадку навігаційної панелі) вміст.

Більшу частину часу вашій програмі не потрібно буде малювати під смужкою стану або навігаційною панеллю, але якщо це потрібно: вам потрібно переконатися, що інтерактивні елементи (наприклад, кнопки) не ховаються під ними. Ось що дає атрибут android: fitsSystemWindows = "true" за замовчуванням: він встановлює вкладку View, щоб вміст не перекривав вікна системи.

https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec


1
Ок, я розумію
MJ Studio

6

вона не тягнеться за системною панеллю, вона наче розтягується за барною смугою, щоб підфарбовувати її тими ж кольорами, які вона має, але перегляди, які вона містить, забиті всередині рядка стану, якщо це має сенс

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.