WindowInsets
, ekranın sistem kullanıcı arayüzü tarafından kısmen veya tamamen kapatılan alanlarını işlemek için Jetpack Compose'daki standart API'dir. Bu alanlar arasında durum çubuğu, gezinme çubuğu ve ekran klavyesi bulunur. Alternatif olarak, içeriğinizi sistem çubukları ve ekran kesimiyle hizalamak için önceden tanımlanmış WindowInsetsRulers
'ları (ör. SafeDrawing
) Modifier.fitInside
'a veya Modifier.fitOutside
'a iletebilir ya da özel WindowInsetsRulers
oluşturabilirsiniz.
WindowInsetsRulers
avantajları
- Tüketim Karmaşıklığını Önler: Düzenin yerleştirme aşamasında çalışır. Bu nedenle, yerleştirilmiş tüketim zincirini tamamen atlar ve üst düzenlerin ne yaptığına bakılmaksızın sistem çubuklarının ve ekran kesiklerinin doğru ve mutlak konumlarını her zaman sağlayabilir.
Modifier.fitInside
veyaModifier.fitOutside
yöntemlerini kullanmak, üst composable'lar yerleştirmeleri yanlış tükettiğinde sorunları düzeltmeye yardımcı olur. - Sistem çubuklarından kolayca kaçının: Uygulama içeriğinizin sistem çubuklarından ve ekran kesiminden kaçınmasına yardımcı olur. Ayrıca, doğrudan
WindowInsets
kullanmaktan daha kolay olabilir. - Yüksek düzeyde özelleştirilebilir: Geliştiriciler, içerikleri özel cetvellerle hizalayabilir ve özel düzenlerle düzenleri üzerinde hassas kontrol sahibi olabilir.
WindowInsetsRulers
ile ilgili dezavantajlar
- Ölçüm için kullanılamaz: Yerleştirme aşamasında çalıştığı için sağladığı konumsal bilgiler, önceki ölçüm aşamasında kullanılamaz.
İçeriğinizi değiştirici yöntemlerle uyumlu hale getirme
Modifier.fitInside
, uygulamaların içeriği sistem çubuklarıyla hizalamasına ve ekran kesiklerini göstermesine olanak tanır. WindowInsets
yerine kullanılabilir. Modifier.fitOutside
genellikle Modifier.fitInside
'ün tersidir.
Örneğin, uygulama içeriğinin sistem çubuklarından ve ekran kesiminden kaçındığını doğrulamak için fitInside(WindowInsetsRulers.safeDrawing.current)
kullanabilirsiniz.
@Composable fun FitInsideDemo(modifier: Modifier) { Box( modifier = modifier .fillMaxSize() // Or DisplayCutout, Ime, NavigationBars, StatusBar, etc... .fitInside(WindowInsetsRulers.SafeDrawing.current) ) }
Aşağıdaki tabloda, uygulamanızın içeriğinin Modifier.fitInside
veya Modifier.fitOutside
ile önceden tanımlanmış cetvellerle nasıl görüneceği gösterilmektedir.
Önceden tanımlanmış cetvel türü | ||
---|---|---|
![]() |
![]() |
|
![]() |
Yok |
|
![]() |
![]() |
|
![]() |
Geçersiz (Bunun yerine |
|
![]() |
![]() |
Modifier.fitInside
ve Modifier.fitOutside
kullanmak için composable'ların kısıtlanması gerekir. Bu, Modifier.size
veya Modifier.fillMaxSize
gibi değiştiriciler tanımlamanız gerektiği anlamına gelir.
Modifier.fitOutside
ve SystemBars
gibi bazı cetveller birden fazla cetvel döndürür.SafeDrawing
Bu durumda Android, Composable'ı soldan, üstten, sağdan veya alttan bir cetvelle yerleştirir.
Modifier.fitInside ile IME'den kaçınma
Modifier.fitInside
ile bir IME'de alttaki öğeleri işlemek için NavigationBar
ve Ime
öğelerinin en içteki değerini alan bir RectRuler
iletin.
@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() ) } }
Modifier.fitInside ile durum çubuğu ve başlık çubuğundan kaçınma
Benzer şekilde, üst öğeleri doğrulamak için durum çubuğu ve başlık çubuğunu Modifier.fitInsider
ile birlikte kullanmaktan kaçının. Bunun yerine, StatusBars
ve CaptionBar
öğelerinin en içteki değerini alan bir RectRuler
iletin.
@Composable fun FitInsideWithStatusAndCaptionBarDemo(modifier: Modifier) { Box( modifier = modifier .fillMaxSize() .fitInside( RectRulers.innermostOf( WindowInsetsRulers.StatusBars.current, WindowInsetsRulers.CaptionBar.current ) ) ) }
Özel WindowInsetsRulers
oluşturma
İçeriği özel cetvellerle hizalayabilirsiniz. Örneğin, bir üst composable'ın, yerleştirmeleri yanlış şekilde işleyerek alt öğede dolgu sorunlarına neden olduğu kullanım alanını ele alalım. Bu sorun, Modifier.fitInside
kullanmak gibi başka yöntemlerle de çözülebilse de aşağıdaki örnekte ve videoda gösterildiği gibi, üst öğede sorunu düzeltmeden alt öğeyi tam olarak hizalamak için özel bir cetvel de oluşturabilirsiniz:
@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) } } } }
Aşağıdaki videoda, soldaki resimde yer alan bir üst öğenin neden olduğu sorunlu IME ekleme tüketimi örneği ve sağ tarafta sorunu düzeltmek için özel cetvellerin kullanımı gösterilmektedir. Gezinme çubuğu dolgusu üst öğe tarafından kullanılmadığı için TextField
Composable'ın altında ekstra dolgu gösteriliyor. Çocuk, önceki kod örneğinde gösterildiği gibi özel bir cetvel kullanılarak sağdaki resimde doğru konuma yerleştiriliyor.
Ebeveynlerin kısıtlandığını doğrulayın
WindowInsetsRulers
özelliğini güvenli bir şekilde kullanmak için ebeveynin geçerli kısıtlamalar sağladığından emin olun. Ebeveynlerin tanımlanmış bir boyutu olmalıdır ve WindowInsetsRulers
kullanan bir çocuğun boyutuna bağlı olamaz. Üst composable'larda fillMaxSize
veya diğer boyut değiştiricileri kullanın.
Benzer şekilde, WindowInsetsRulers
kullanan bir composable'ı verticalScroll
gibi kaydırma kapsayıcısının içine yerleştirmek de beklenmedik davranışlara neden olabilir. Bunun nedeni, kaydırma kapsayıcısının, cetvelin mantığıyla uyumlu olmayan sınırsız yükseklik kısıtlamaları sağlamasıdır.