Co dokładnie robi fitSystemWindows?


126

Staram się zrozumieć koncepcję, że fitsSystemWindowsw zależności od poglądu robi różne rzeczy. Zgodnie z oficjalną dokumentacją jest to plik

Wewnętrzny atrybut logiczny, aby dostosować układ widoku na podstawie okien systemowych, takich jak pasek stanu. Jeśli tak, dostosowuje wypełnienie tego widoku, aby zostawić miejsce na okna systemowe .

Teraz, sprawdzając View.javaklasę, widzę, że gdy jest ustawiona na true, wstawki okna (pasek stanu, pasek nawigacji ...) są stosowane do paddings widoku, co działa zgodnie z cytowaną powyżej dokumentacją. To jest odpowiednia część kodu:

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

Wraz z nowym Material Design pojawiły się nowe klasy, które w szerokim zakresie wykorzystują tę flagę i tutaj pojawia się zamieszanie. W wielu źródłach fitsSystemWindowsjest wymieniany jako flaga ustawiana, aby umieścić widok za kratkami systemu. Zobacz tutaj .

Dokumentacja ViewCompat.javaza setFitsSystemWindowsmówi:

Określa, czy ten widok powinien uwzględniać dekoracje ekranu systemu, takie jak pasek stanu, i wstawiać jego zawartość; to znaczy kontrolowanie, czy zostanie wykonana domyślna implementacja {@link View # fitSystemWindows (Rect)}. Zobacz tę metodę, aby uzyskać więcej informacji .

Zgodnie z tym, fitsSystemWindowspo prostu oznacza, że funkcja fitsSystemWindows()zostanie wykonana? Wydaje się, że nowe klasy materiałów używają tego po prostu do rysowania pod paskiem stanu. Jeśli spojrzymy na DrawerLayout.javakod, zobaczymy to:

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

I widzimy ten sam wzór w nowym CoordinatorLayoutlub AppBarLayout.

Czy to nie działa w dokładnie odwrotny sposób niż dokumentacja fitsSystemWindows? W ostatnich przypadkach oznacza to rysowanie za kratkami systemu .

Jeśli jednak chcesz, aby a FrameLayoutrysował się za paskiem stanu, ustawienie fitsSystemWindowsna true nie załatwia sprawy, ponieważ domyślna implementacja robi to, co zostało początkowo udokumentowane. Musisz go nadpisać i dodać te same flagi, co inne wspomniane klasy. Czy coś mi brakuje?


1
Wygląda na to, że jest to błąd, opublikowałem raport o błędzie w narzędziu do śledzenia problemów z Androidem
Tim Rae


Dzięki za link, bardzo przydatne. Mimo to potwierdza, że ​​są tam niespójności. Na połączonej stronie jest napisane, że niektóre z nowych widżetów, na przykład CoordinatorLayout, używają tej flagi do wywnioskowania, czy powinny malować za paskiem stanu, czy nie. Na FrameLayoutprzykład tak nie jest.
Przypnij

2
To było świetne pytanie i bardzo fajna praca nad kodem źródłowym Androida. Szczególnie doceniam to, że zidentyfikowałeś, w jaki sposób nowe klasy MD radzą sobie z dopasowaniem doSystemWindows ... Szalałem, próbując to rozgryźć!
coolDude

Odpowiedzi:


19

Okna systemowe to części ekranu, w których system rysuje zawartość nieinteraktywną (w przypadku paska stanu) lub interaktywną (w przypadku paska nawigacji).

W większości przypadków aplikacja nie będzie musiała rysować pod paskiem stanu lub paskiem nawigacji, ale jeśli to zrobisz: upewnij się, że elementy interaktywne (takie jak przyciski) nie są ukryte pod nimi. Właśnie to daje domyślne zachowanie atrybutu android: fitSystemWindows = „true”: ustawia on dopełnienie widoku, aby zapewnić, że zawartość nie nakłada się na okna systemowe.

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


1
Ok, rozumiem
MJ Studio

6

nie rysuje się za paskiem systemowym, jakby rozciąga się za paskiem, aby zabarwić go tymi samymi kolorami, które ma, ale widoki, które zawiera, są wyściełane wewnątrz paska stanu, jeśli ma to sens

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.