Was genau macht fitSystemWindows?

126

Ich kämpfe darum, das Konzept zu verstehen, dass es fitsSystemWindowsje nach Ansicht unterschiedliche Dinge bewirkt. Laut offizieller Dokumentation ist es ein

Boolesches internes Attribut zum Anpassen des Ansichtslayouts basierend auf Systemfenstern wie der Statusleiste. Wenn true, wird der Abstand dieser Ansicht angepasst , um Platz für die Systemfenster zu lassen .

View.javaWenn ich nun die Klasse überprüfe, kann ich sehen, dass bei Einstellung auf truedie Fenstereinfügungen (Statusleiste, Navigationsleiste ...) auf die Ansichtsauffüllungen angewendet werden, was gemäß der oben zitierten Dokumentation funktioniert. Dies ist der relevante Teil des Codes:

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;
}

Mit dem neuen Materialdesign gibt es neue Klassen, die diese Flagge in großem Umfang nutzen, und hier kommt die Verwirrung. In vielen Quellen fitsSystemWindowswird als Flag zum Setzen der Ansicht hinter den Systemleisten erwähnt. Siehe hier .

Die Dokumentation in ViewCompat.javafor setFitsSystemWindowssagt:

Legt fest, ob diese Ansicht Systembildschirmdekorationen wie die Statusleiste berücksichtigen soll, und fügt deren Inhalt ein. Das heißt, Sie steuern, ob die Standardimplementierung von {@link View # fitSystemWindows (Rect)} ausgeführt wird. Weitere Informationen finden Sie in dieser Methode .

Bedeutet das fitsSystemWindowseinfach, dass die Funktion fitsSystemWindows()ausgeführt wird? Die neuen Materialklassen scheinen dies nur zum Zeichnen unter der Statusleiste zu verwenden. Wenn wir uns DrawerLayout.javaden Code ansehen , können wir Folgendes sehen:

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);
    }
}

Und wir sehen das gleiche Muster im neuen CoordinatorLayoutoder AppBarLayout.

Funktioniert das nicht genau umgekehrt wie die Dokumentation für fitsSystemWindows? In den letzten Fällen bedeutet dies , hinter die Systemstangen zu ziehen .

Wenn Sie jedoch möchten FrameLayout, dass sich a hinter die Statusleiste zieht, reicht die Einstellung fitsSystemWindowsauf true nicht aus, da die Standardimplementierung das tut, was ursprünglich dokumentiert wurde. Sie müssen es überschreiben und die gleichen Flags wie die anderen genannten Klassen hinzufügen. Vermisse ich etwas

Stift
quelle
1
Dies scheint ein Fehler zu sein. Ich habe einen Fehlerbericht auf dem Android Issue Tracker veröffentlicht
Tim Rae
1
Überprüfen Sie hier: medium.com/google-developers/…
Fatih S.
Danke für den Link, sehr nützlich. Dennoch bestätigt es, dass es dort Inkonsistenzen gibt. Auf der verlinkten Seite heißt es, dass einige der neuen Widgets, z. B. CoordinatorLayoutdieses Flag, verwenden, um zu schließen, ob sie hinter der Statusleiste malen sollen oder nicht. Das ist FrameLayoutzum Beispiel nicht der Fall .
Pin
2
Dies war eine großartige Frage und eine sehr gute Arbeit beim Betrachten des Android-Quellcodes. Ich habe besonders geschätzt, dass Sie festgestellt haben, wie die neuen MD-Klassen mit fitSystemWindows anders umgehen ... Ich war verrückt, als ich versuchte, das herauszufinden!
coolDude

Antworten:

19

Systemfenster sind die Teile des Bildschirms, in denen das System entweder nicht interaktive (im Fall der Statusleiste) oder interaktive (im Fall der Navigationsleiste) Inhalte zeichnet.

Meistens muss Ihre App nicht unter der Statusleiste oder der Navigationsleiste zeichnen. Wenn Sie dies jedoch tun, müssen Sie sicherstellen, dass interaktive Elemente (wie Schaltflächen) nicht darunter verborgen sind. Das ist das Standardverhalten des Attributs android: fitSystemWindows = "true": Es legt den Abstand der Ansicht fest, um sicherzustellen, dass der Inhalt die Systemfenster nicht überlagert.

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

iljyya
quelle
1
Ok, ich verstehe
MJ Studio
6

Es wird nicht hinter die Systemleiste gezeichnet, sondern hinter die Leiste, um sie mit den gleichen Farben zu tönen. Die darin enthaltenen Ansichten werden jedoch in der Statusleiste aufgefüllt, wenn dies sinnvoll ist

Hala.M
quelle