WindowInsets adalah API standar di Jetpack Compose untuk menangani area layar yang sebagian atau seluruhnya terhalang oleh UI sistem. Area ini mencakup status bar, menu navigasi, dan keyboard di layar. Anda dapat
secara alternatif 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.
Keuntungan WindowInsetsRulers
- Menghindari Kompleksitas Konsumsi: Beroperasi selama fase penempatan
tata letak. Artinya, rantai konsumsi inset akan dilewati sepenuhnya 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 Composables ancestor salah menggunakan inset. - Menghindari kolom sistem dengan mudah: Membantu konten aplikasi menghindari kolom sistem
dan potongan layar, serta dapat lebih mudah daripada menggunakan
WindowInsetssecara langsung. - Sangat dapat disesuaikan: Developer dapat menyelaraskan konten ke penggaris kustom, dan memiliki kontrol yang tepat atas tata letak 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 Modifier
Modifier.fitInside memungkinkan aplikasi menyelaraskan konten ke 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 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 caption bar dengan Modifier.fitInside
Demikian pula, untuk memverifikasi elemen atas menghindari status bar dan caption bar bersama dengan Modifier.fitInsider, 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 ke penggaris kustom. Misalnya, pertimbangkan kasus penggunaan saat composable induk menangani inset dengan tidak benar sehingga menyebabkan masalah padding pada turunan hilir. Meskipun masalah ini dapat diselesaikan dengan cara lain, termasuk menggunakan Modifier.fitInside, Anda juga dapat membuat penggaris kustom untuk menyelaraskan 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 Composable TextField karena padding menu navigasi tidak digunakan oleh induk. Turunan 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 dapat bergantung pada ukuran turunan yang menggunakan WindowInsetsRulers. Gunakan fillMaxSize atau pengubah ukuran lainnya pada Composables 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.







