Apa sebenarnya yang dilakukan fitSystemWindows?

126

Saya berjuang untuk memahami konsep fitsSystemWindowskarena bergantung pada pandangan, ia melakukan hal yang berbeda. Menurut dokumentasi resmi itu a

Atribut internal Boolean untuk menyesuaikan tata letak tampilan berdasarkan jendela sistem seperti bilah status. Jika benar, sesuaikan bantalan pada tampilan ini untuk menyisakan ruang untuk jendela sistem .

Sekarang, memeriksa View.javakelas saya dapat melihat bahwa ketika diatur ke true, sisipan jendela (bilah status, bilah navigasi ...) diterapkan ke bantalan tampilan, yang berfungsi sesuai dengan dokumentasi yang dikutip di atas. Ini adalah bagian yang relevan dari kode:

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

Dengan desain Material baru, ada kelas-kelas baru yang menggunakan flag ini secara ekstensif dan di sinilah kebingungan datang. Dalam banyak sumber fitsSystemWindowsdisebutkan sebagai tanda yang akan disetel untuk meletakkan tampilan di belakang bilah sistem. Lihat disini .

Dokumentasi di ViewCompat.javafor setFitsSystemWindowsmengatakan:

Menyetel apakah tampilan ini harus memperhitungkan dekorasi layar sistem seperti bilah status dan menyisipkan isinya atau tidak; yaitu, mengontrol apakah implementasi default {@link View # fitSystemWindows (Rect)} akan dijalankan. Lihat metode itu untuk lebih jelasnya .

Menurut ini, fitsSystemWindowsberarti fungsi fitsSystemWindows()tersebut akan dieksekusi? Kelas Material baru tampaknya hanya menggunakan ini untuk menggambar di bawah bilah status. Jika kita melihat DrawerLayout.javakode, kita dapat melihat ini:

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

Dan kami melihat pola yang sama di baru CoordinatorLayoutatau AppBarLayout.

Bukankah ini bekerja dengan cara yang berlawanan dengan dokumentasinya fitsSystemWindows? Dalam kasus terakhir, itu berarti menarik di belakang palang sistem .

Namun, jika Anda ingin a FrameLayoutmenggambar dirinya sendiri di belakang bilah status, menyetel fitsSystemWindowske true tidak melakukan trik karena implementasi default melakukan apa yang didokumentasikan pada awalnya. Anda harus menimpanya dan menambahkan flag yang sama dengan kelas yang disebutkan lainnya. Apakah saya melewatkan sesuatu?

Pin
sumber
1
Sepertinya ini bug, saya telah memposting laporan bug di pelacak masalah Android
Tim Rae
1
Periksa di sini: medium.com/google-developers/…
Fatih S.
Terima kasih untuk tautannya, sangat berguna. Namun, itu menegaskan bahwa ada ketidakkonsistenan di sana. Di halaman tertaut dikatakan bahwa beberapa widget baru, seperti CoordinatorLayout, menggunakan bendera itu untuk menyimpulkan apakah mereka harus melukis di belakang status bar atau tidak. Tidak demikian halnya dengan FrameLayout, misalnya.
Pin
2
Ini adalah pertanyaan yang bagus dan kerja yang sangat bagus melihat kode sumber Android. Saya sangat menghargai bahwa Anda mengidentifikasi bagaimana kelas MD baru menangani cocokSystemWindows secara berbeda .... Saya menjadi gila mencoba mencari tahu ini!
coolDude

Jawaban:

19

Jendela sistem adalah bagian dari layar tempat sistem menggambar konten non-interaktif (dalam kasus bilah status) atau interaktif (dalam kasus bilah navigasi).

Sering kali, aplikasi Anda tidak perlu menggambar di bawah bilah status atau bilah navigasi, tetapi jika Anda melakukannya: Anda perlu memastikan elemen interaktif (seperti tombol) tidak tersembunyi di bawahnya. Itulah yang diberikan perilaku default dari atribut android: fitSystemWindows = "true": ini menyetel pengisi View untuk memastikan konten tidak menutupi jendela sistem.

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

iljyya
sumber
1
Oke, saya mengerti
MJ Studio
6

itu tidak menggambar di belakang bilah sistem itu semacam membentang di belakang bilah untuk mewarnai dengan warna yang sama yang dimilikinya tetapi tampilan yang dikandungnya dimasukkan di dalam bilah status jika itu masuk akal

Hala.M
sumber