WindowInsets adalah API standar di Jetpack Compose untuk menangani
area layar yang sebagian atau sepenuhnya terhalang oleh UI sistem. Area ini mencakup status bar, menu navigasi, dan keyboard virtual. Atau, Anda dapat
meneruskan WindowInsetsRulers yang telah ditentukan seperti
SafeDrawing ke Modifier.fitInside atau Modifier.fitOutside
untuk menyelaraskan konten dengan kolom sistem dan potongan layar atau membuat
WindowInsetsRulers kustom.
Keunggulan WindowInsetsRulers
- Menghindari Kompleksitas Konsumsi: Modifier ini beroperasi selama fase penempatan
tata letak. Artinya, API ini sepenuhnya mengabaikan rantai pemakaian inset dan
selalu dapat memberikan posisi absolut yang benar dari kolom sistem dan potongan
layar, terlepas dari apa yang telah dilakukan tata letak induk. Menggunakan
metode
Modifier.fitInsideatauModifier.fitOutsideakan membantu memperbaiki masalah saat Composable ancestor menggunakan inset secara tidak tepat. - Menghindari kolom sistem dengan mudah: Membantu konten aplikasi Anda menghindari kolom sistem
dan potongan layar, serta dapat lebih mudah daripada menggunakan
WindowInsetssecara 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.
Menyelaraskan konten dengan metode Pengubah
Modifier.fitInside memungkinkan aplikasi menyelaraskan konten dengan kolom sistem dan
potongan layar. Metode ini dapat digunakan sebagai pengganti WindowInsets.
Modifier.fitOutside biasanya merupakan kebalikan dari Modifier.fitInside.
Misalnya, untuk memverifikasi bahwa konten aplikasi menghindari kolom sistem dan potongan
layar, Anda dapat menggunakan fitInside(WindowInsetsRulers.safeDrawing.current).
@Composable fun FitInsideDemo(modifier: Modifier) { Box( modifier = modifier .fillMaxSize() // Or DisplayCutout, Ime, NavigationBars, StatusBar, etc... .fitInside(WindowInsetsRulers.SafeDrawing.current) ) }
Tabel berikut menunjukkan tampilan konten aplikasi Anda dengan penggaris
yang telah ditentukan sebelumnya dengan Modifier.fitInside atau Modifier.fitOutside.
| Jenis penggaris yang telah ditentukan | ||
|---|---|---|
![]() |
![]() |
|
![]() |
T/A |
|
![]() |
![]() |
|
![]() |
T/A (gunakan |
|
![]() |
![]() |
Penggunaan Modifier.fitInside dan Modifier.fitOutside mengharuskan
composable dibatasi. Artinya, Anda harus menentukan pengubah seperti
Modifier.size atau Modifier.fillMaxSize.
Beberapa penggaris seperti Modifier.fitOutside di SafeDrawing dan SystemBars menampilkan
beberapa penggaris. Dalam hal ini, Android menempatkan Composable menggunakan satu penggaris
dari kiri, atas, kanan, bawah.
Menghindari IME dengan Modifier.fitInside
Untuk menangani elemen bawah dengan IME dengan Modifier.fitInside, teruskan
RectRuler yang mengambil nilai terdalam dari NavigationBar dan Ime.
@Composable fun FitInsideWithImeDemo(modifier: Modifier) { Box( modifier = modifier .fillMaxSize() .fitInside( RectRulers.innermostOf( WindowInsetsRulers.NavigationBars.current, WindowInsetsRulers.Ime.current ) ) ) { TextField( value = "Demo IME Insets", onValueChange = {}, modifier = modifier.align(Alignment.BottomStart).fillMaxWidth() ) } }
Menghindari status bar dan panel teks dengan Modifier.fitInside
Demikian pula, untuk memverifikasi elemen teratas menghindari status bar dan panel teks bersama
dengan Modifier.fitInside, teruskan RectRuler yang mengambil nilai terdalam dari
StatusBars dan CaptionBar.
@Composable fun FitInsideWithStatusAndCaptionBarDemo(modifier: Modifier) { Box( modifier = modifier .fillMaxSize() .fitInside( RectRulers.innermostOf( WindowInsetsRulers.StatusBars.current, WindowInsetsRulers.CaptionBar.current ) ) ) }
Membuat WindowInsetsRulers kustom
Anda dapat menyelaraskan konten dengan penggaris kustom. Misalnya, pertimbangkan kasus penggunaan saat
composable induk menangani inset secara tidak tepat sehingga menyebabkan masalah padding di
turunan downstream. Meskipun masalah ini dapat diselesaikan dengan cara lain, termasuk dengan
menggunakan Modifier.fitInside, Anda juga dapat membuat penggaris kustom untuk meratakan
composable turunan secara tepat 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 pada gambar di sebelah kiri, dan menggunakan penggaris kustom
untuk memperbaiki masalah di sebelah kanan. Padding tambahan ditampilkan di bawah TextField
Composable karena padding menu navigasi tidak digunakan oleh induk. Anak
ditempatkan di lokasi yang benar pada gambar kanan menggunakan penggaris kustom
seperti yang terlihat dalam contoh kode sebelumnya.
Memastikan induk dibatasi
Agar dapat menggunakan WindowInsetsRulers dengan aman, pastikan induk memberikan batasan yang valid. Induk harus memiliki ukuran yang ditentukan dan tidak boleh 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.







