FitsSystemWindows tam olarak ne yapıyor?


126

Kavramını anlamakta zorlanıyorum fitsSystemWindowsFarklı şeyler yaptığı görüşüne bağlı olarak . Resmi belgelere göre bu bir

Durum çubuğu gibi sistem pencerelerine göre görünüm düzenini ayarlamak için Boolean dahili özniteliği. Doğruysa, bu görünümün dolgusunu sistem pencereleri için alan bırakacak şekilde ayarlar .

Şimdi, View.javasınıfa truebaktığımda, ayarlandığında pencere iç metinlerinin (durum çubuğu, gezinme çubuğu ...) yukarıda alıntılanan belgelere göre çalışan görünüm dolgularına uygulandığını görebiliyorum. Bu, kodun ilgili kısmıdır:

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

Yeni Materyal tasarımıyla, bu bayrağı kapsamlı bir şekilde kullanan yeni sınıflar var ve karışıklık işte tam da bu noktada geliyor. Birçok kaynakta fitsSystemWindows, görünümü sistem çubuklarının arkasına yerleştirmek için ayarlanacak bayrak olarak bahsedilir. Buraya bakın .

Dokümantasyon ViewCompat.javaiçin setFitsSystemWindowsdiyor ki:

Bu görünümün durum çubuğu gibi sistem ekranı dekorasyonlarını hesaba katıp katmayacağını belirler ve içeriğini ekler; yani, varsayılan {@link View # fitSystemWindows (Rect)} uygulamasının çalıştırılıp çalıştırılmayacağını kontrol etmek. Daha fazla ayrıntı için bu yönteme bakın .

Buna göre, fitsSystemWindowsbasitçe işlevin fitsSystemWindows()yürütüleceği anlamına mı geliyor? Yeni Materyal sınıfları bunu sadece durum çubuğunun altında çizim yapmak için kullanıyor gibi görünüyor. Koduna bakarsak DrawerLayout.java, şunu görebiliriz:

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

Yeni CoordinatorLayoutveya yeni modelde aynı kalıbı görüyoruzAppBarLayout .

Bu, dokümantasyonun tam tersi şekilde çalışmıyor mu fitsSystemWindows? Son durumlarda, sistem çubuklarının arkasına çekmek anlamına gelir .

Bununla birlikte, FrameLayouta'nın kendisini durum çubuğunun arkasına çekmesini istiyorsanız fitsSystemWindows, varsayılan uygulama başlangıçta belgelenen şeyi yaptığından true olarak ayarlamak işe yaramaz. Bunu geçersiz kılmalı ve belirtilen diğer sınıflarla aynı bayrakları eklemelisiniz. Bir şey mi kaçırıyorum?


1
Bu bir hata gibi görünüyor , Android sorun izleyicisine bir hata raporu gönderdim
Tim Rae


Bağlantı için teşekkürler, çok kullanışlı. Yine de orada tutarsızlıklar olduğunu doğrular. Bağlantılı sayfada, bazı yeni widget'ların CoordinatorLayoutdurum çubuğunun arkasını boyayıp boyamayacaklarını anlamak için bu bayrağı kullandıklarını söylüyor. FrameLayoutÖrneğin durum böyle değil .
Pim

2
Bu harika bir soruydu ve Android kaynak koduna bakıldığında çok güzel bir işti. Yeni MD sınıflarının SystemWindows'a nasıl farklı uyduğunu tanımladığınız için özellikle minnettarım .... Bunu anlamaya çalışırken deliriyordum!
coolDude

Yanıtlar:


19

Sistem pencereleri, sistemin etkileşimli olmayan (durum çubuğu olması durumunda) veya etkileşimli (gezinme çubuğu olması durumunda) içerik çizdiği ekran parçalarıdır.

Çoğu zaman, uygulamanızın durum çubuğunun veya gezinme çubuğunun altına çizilmesi gerekmez, ancak bunu yaparsanız: Etkileşimli öğelerin (düğmeler gibi) altlarında gizlenmediğinden emin olmanız gerekir. Android'in varsayılan davranışı budur: fitsSystemWindows = "true" özniteliği size verir: İçeriğin sistem pencerelerini kaplamamasını sağlamak için Görünümün dolgusunu ayarlar.

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


1
Tamam anladım
MJ Studio

6

sistem çubuğunun arkasına çekilmez, sahip olduğu aynı renklerle renklendirmek için çubuğun arkasına uzanır, ancak içerdiği görünümler, mantıklıysa durum çubuğunun içinde doldurulur

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.