WindowInsets
adalah API standar di Jetpack Compose untuk menangani
area layar yang sebagian atau seluruhnya tertutup oleh UI sistem. Area ini mencakup status bar, menu navigasi, dan keyboard virtual. Sebagai alternatif, Anda dapat meneruskan WindowInsetsRulers
yang telah ditentukan sebelumnya seperti SafeDrawing
ke
Modifier.fitInside
atau Modifier.fitOutside
untuk menyelaraskan konten Anda
dengan kolom sistem dan potongan layar atau membuat WindowInsetsRulers
kustom.
Keuntungan WindowInsetsRulers
- Menghindari Kompleksitas Penggunaan: Beroperasi selama fase penempatan
tata letak. Artinya, ini sepenuhnya melewati rantai konsumsi inset dan
selalu dapat memberikan posisi absolut yang benar dari kolom sistem dan potongan
layar, terlepas dari apa yang telah dilakukan tata letak induk. Penggunaan metode
Modifier.fitInside
atauModifier.fitOutside
berguna dalam memperbaiki masalah saat Composable induk menggunakan inset secara tidak benar. - Menghindari kolom sistem dengan mudah: Membantu konten aplikasi Anda menghindari kolom sistem dan potongan layar, serta dapat lebih mudah daripada menggunakan
WindowInsets
secara langsung. - Sangat dapat disesuaikan: Developer dapat menyelaraskan konten dengan penggaris kustom, dan memiliki kontrol yang akurat atas tata letak mereka dengan tata letak kustom.
Kekurangan WindowInsetsRulers
- Tidak dapat digunakan untuk Pengukuran: Karena beroperasi selama fase penempatan, informasi posisi yang diberikannya tidak tersedia selama fase pengukuran sebelumnya.
- Potensi Ketidakstabilan Tata Letak: Hal ini dapat menyebabkan error jika ukuran tata letak induk bergantung pada ukuran turunannya. Karena turunan yang menggunakan
WindowInsetsRulers
dapat mengubah posisi atau ukurannya selama penempatan, hal ini dapat membuat siklus tata letak yang tidak stabil.
Membuat WindowInsetsRulers
kustom
Anda dapat menyelaraskan konten dengan penggaris kustom. Misalnya, pertimbangkan kasus penggunaan saat
composable induk menangani inset secara tidak benar sehingga menyebabkan masalah padding di
turunan hilir. Meskipun masalah ini dapat diselesaikan dengan cara lain, termasuk dengan
menggunakan Modifier.fitInside
, Anda juga dapat membuat penggaris kustom untuk menyelaraskan
composable turunan secara presisi tanpa harus memperbaiki masalah di induk
upstream seperti yang ditunjukkan dalam contoh dan video berikut:
@Composable fun WindowInsetsRulersDemo(modifier: Modifier) { Box( contentAlignment = BottomCenter, modifier = modifier .fillMaxSize() // The mistake that causes issues downstream, as .padding doesn't consume insets. // While it's correct to instead use .windowInsetsPadding(WindowInsets.navigationBars), // assume it's difficult to identify this issue to see how WindowInsetsRulers can help. .padding(WindowInsets.navigationBars.asPaddingValues()) ) { TextField( value = "Demo IME Insets", onValueChange = {}, modifier = modifier // Use alignToSafeDrawing() instead of .imePadding() to precisely place this child // Composable without having to fix the parent upstream. .alignToSafeDrawing() // .imePadding() // .fillMaxWidth() ) } } fun Modifier.alignToSafeDrawing(): Modifier { return layout { measurable, constraints -> if (constraints.hasBoundedWidth && constraints.hasBoundedHeight) { val placeable = measurable.measure(constraints) val width = placeable.width val height = placeable.height layout(width, height) { val bottom = WindowInsetsRulers.SafeDrawing.current.bottom .current(0f).roundToInt() - height val right = WindowInsetsRulers.SafeDrawing.current.right .current(0f).roundToInt() val left = WindowInsetsRulers.SafeDrawing.current.left .current(0f).roundToInt() measurable.measure(Constraints.fixed(right - left, height)) .place(left, bottom) } } else { val placeable = measurable.measure(constraints) layout(placeable.width, placeable.height) { placeable.place(0, 0) } } } }
Video berikut menunjukkan contoh konsumsi inset IME yang bermasalah yang disebabkan oleh induk upstream dalam gambar di sebelah kiri, dan menggunakan penggaris kustom untuk memperbaiki masalah di sebelah kanan. Padding tambahan ditampilkan di bawah Composable TextField
karena padding menu navigasi tidak digunakan oleh induk. Anak ditempatkan di lokasi yang benar dalam gambar kanan menggunakan penggaris kustom seperti yang terlihat dalam contoh kode sebelumnya.
Verifikasi bahwa orang tua dibatasi
Untuk menggunakan WindowInsetsRulers
dengan aman, pastikan induk memberikan batasan yang valid. Induk harus memiliki ukuran yang ditentukan dan tidak dapat bergantung pada ukuran
turunan yang menggunakan WindowInsetsRulers
. Gunakan fillMaxSize
atau pengubah ukuran lainnya
pada Composable induk.
Demikian pula, menempatkan composable yang menggunakan WindowInsetsRulers
di dalam
penampung scroll seperti verticalScroll
dapat menyebabkan perilaku yang tidak terduga karena
penampung scroll memberikan batasan tinggi yang tidak terbatas, yang
tidak kompatibel dengan logika penggaris.