WindowInsets
to standardowy interfejs API w Jetpack Compose do obsługi obszarów ekranu, które są częściowo lub całkowicie zasłonięte przez interfejs systemu. Obejmują one pasek stanu, pasek nawigacji i klawiaturę ekranową. Możesz też przekazać predefiniowane wartości WindowInsetsRulers
, takie jak SafeDrawing
do Modifier.fitInside
lub Modifier.fitOutside
, aby dopasować treść do pasków systemowych i wycięcia na wyświetlaczu, lub utworzyć niestandardowe wartości WindowInsetsRulers
.
Zalety WindowInsetsRulers
- Unika złożoności związanej z wykorzystaniem: działa w fazie umieszczania układu. Oznacza to, że całkowicie pomija łańcuch konsumpcji wstawki i zawsze może podać prawidłowe, bezwzględne pozycje pasków systemowych i wycięć wyświetlacza, niezależnie od tego, co zrobiły układy nadrzędne. Użycie metod
Modifier.fitInside
lubModifier.fitOutside
pomaga rozwiązać problemy, gdy elementy kompozycyjne nadrzędne nieprawidłowo wykorzystują wstawki. - Łatwe unikanie pasków systemowych: pomaga uniknąć pasków systemowych i wycięcia na wyświetlaczu, a może być prostsze niż bezpośrednie używanie
WindowInsets
. - Duże możliwości dostosowywania: deweloperzy mogą dopasowywać treści do niestandardowych linijek i precyzyjnie kontrolować układy za pomocą układów niestandardowych.
Wady WindowInsetsRulers
- Nie można używać do pomiarów: ponieważ działa w fazie umieszczania, informacje o pozycji, które dostarcza, są niedostępne w poprzedniej fazie pomiaru.
- Potencjalna niestabilność układu: może powodować awarie, jeśli rozmiar układu nadrzędnego zależy od rozmiaru elementów podrzędnych. Ponieważ dziecko korzystające z
WindowInsetsRulers
może zmienić swoje położenie lub rozmiar podczas umieszczania, może to spowodować niestabilny cykl układu.
Tworzenie niestandardowego celu WindowInsetsRulers
Możesz wyrównać treści do niestandardowych linijek. Rozważmy na przykład przypadek, w którym funkcja kompozycyjna nadrzędna nieprawidłowo obsługuje wstawki, co powoduje problemy z dopełnieniem w funkcji kompozycyjnej podrzędnej. Ten problem można rozwiązać na inne sposoby, np. za pomocą Modifier.fitInside
. Możesz też utworzyć niestandardową linijkę, aby precyzyjnie wyrównać element kompozycyjny podrzędny bez konieczności rozwiązywania problemu w elemencie nadrzędnym, jak pokazano w tym przykładzie i filmie:
@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) } } } }
Poniższy film pokazuje przykład problematycznego wykorzystania wstawki IME spowodowanego przez element nadrzędny w obrazie po lewej stronie oraz użycie niestandardowych linijek w celu rozwiązania problemu po prawej stronie. Pod elementem TextField
Composable widać dodatkowe dopełnienie, ponieważ dopełnienie paska nawigacyjnego nie zostało wykorzystane przez element nadrzędny. Element podrzędny jest umieszczany we właściwym miejscu na prawym obrazie za pomocą niestandardowej linijki, jak widać w przykładowym kodzie powyżej.
Sprawdzanie, czy rodzice mają ograniczenia
Aby bezpiecznie korzystać z WindowInsetsRulers
, rodzic musi podać prawidłowe ograniczenia. Elementy nadrzędne muszą mieć określony rozmiar i nie mogą zależeć od rozmiaru elementu podrzędnego, który używa WindowInsetsRulers
. Użyj właściwości fillMaxSize
lub innych modyfikatorów rozmiaru w komponentach nadrzędnych.
Podobnie umieszczenie komponentu kompozycyjnego, który używa WindowInsetsRulers
, w kontenerze przewijanym, takim jak verticalScroll
, może spowodować nieoczekiwane działanie, ponieważ kontener przewijany zapewnia nieograniczone ograniczenia wysokości, które są niezgodne z logiką linijki.