WindowInsetsRulers hakkında

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 veya Modifier.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.
  • Düzenin Kararsız Olma Potansiyeli: Bir üst düzenin boyutu alt düzenlerinin boyutuna bağlıysa bu durum çökmelere neden olabilir. WindowInsetsRulers kullanan bir çocuk, yerleştirme sırasında konumunu veya boyutunu değiştirebileceğinden kararsız bir düzen döngüsü oluşturabilir.

Ö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, kaydırma kapsayıcısı sınırsız yükseklik kısıtlamaları sağladığı için beklenmedik davranışlara neden olabilir. Bu kısıtlamalar, cetvelin mantığıyla uyumlu değildir.