Cosa fa esattamente FitSystemWindows?


126

Sto lottando per capire il concetto di fitsSystemWindowscome dipende dalla vista che fa cose diverse. Secondo la documentazione ufficiale è a

Attributo interno booleano per regolare il layout della vista in base alle finestre di sistema come la barra di stato. Se vero, regola il riempimento di questa vista per lasciare spazio alle finestre di sistema .

Ora, controllando la View.javaclasse, vedo che, quando impostato su true, gli inserti della finestra (barra di stato, barra di navigazione ...) vengono applicati ai padding della vista, che funzionano secondo la documentazione sopra citata. Questa è la parte rilevante del codice:

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

Con il nuovo design dei materiali ci sono nuove classi che fanno ampio uso di questa bandiera ed è qui che nasce la confusione. In molte fonti fitsSystemWindowsè menzionato come la bandiera per impostare la vista dietro le barre di sistema. Vedi qui .

La documentazione in ViewCompat.javaper setFitsSystemWindowsdice:

Imposta se questa vista deve tenere conto delle decorazioni dello schermo del sistema come la barra di stato e inserirne il contenuto; vale a dire, controllando se verrà eseguita l'implementazione predefinita di {@link View # fitSystemWindows (Rect)}. Vedi quel metodo per maggiori dettagli .

Secondo questo, fitsSystemWindowssignifica semplicemente che la funzione fitsSystemWindows()verrà eseguita? Le nuove classi di materiali sembrano usarlo solo per disegnare nella barra di stato. Se guardiamo DrawerLayout.javail codice di, possiamo vedere questo:

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

E vediamo lo stesso modello nel nuovo CoordinatorLayouto AppBarLayout.

Non funziona esattamente nel senso opposto rispetto alla documentazione per fitsSystemWindows? Negli ultimi casi, significa disegnare dietro le barre di sistema .

Tuttavia, se si desidera FrameLayoutdisegnare dietro la barra di stato, l'impostazione fitsSystemWindowssu true non risolve il problema poiché l'implementazione predefinita fa ciò che è documentato inizialmente. Devi sovrascriverlo e aggiungere gli stessi flag delle altre classi menzionate. Mi sto perdendo qualcosa?


1
Sembra un bug, ho pubblicato una segnalazione di bug sul tracker dei problemi di Android
Tim Rae,


Grazie per il link, molto utile. Tuttavia, conferma che ci sono incoerenze lì. Nella pagina collegata dice che alcuni dei nuovi widget, come ad esempio CoordinatorLayout, usano quel flag per dedurre se devono dipingere dietro la barra di stato o meno. Questo non è il caso FrameLayout, ad esempio.
Pin

2
Questa è stata una domanda così bella e un lavoro molto bello esaminando il codice sorgente di Android. Ho particolarmente apprezzato il fatto che tu abbia identificato il modo in cui le nuove classi MD gestiscono FitSystemWindows in modo diverso ... Stavo impazzendo cercando di capirlo!
coolDude,

Risposte:


19

Le finestre di sistema sono le parti dello schermo in cui il sistema sta disegnando contenuti non interattivi (nel caso della barra di stato) o interattivi (nel caso della barra di navigazione).

Il più delle volte, l'app non dovrà disegnare sotto la barra di stato o la barra di navigazione, ma se lo fai: devi assicurarti che gli elementi interattivi (come i pulsanti) non siano nascosti sotto di essi. Questo è ciò che ti dà il comportamento predefinito di Android: fitsSystemWindows = attributo "true": imposta il riempimento della vista per garantire che i contenuti non si sovrappongano alle finestre di sistema.

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


1
Ok ho capito
MJ Studio

6

non si disegna dietro la barra di sistema, si allunga in qualche modo dietro la barra per colorarlo con gli stessi colori che ha ma le viste che contiene sono riempite all'interno della barra di stato se questo ha senso

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.