Gdy Twoja aktywność przejmie kontrolę nad obsługą wszystkich odcięć, możesz użyć interfejsów API Compose, aby sprawdzić, czy treści nie są zasłonięte, a elementy interaktywne nie nakładają się na interfejs systemu. Te interfejsy API synchronizują też układ aplikacji ze zmianami odcięć.
Obsługa odcięć za pomocą modyfikatorów dopełnienia lub rozmiaru
Oto na przykład najbardziej podstawowa metoda stosowania odcięć do treści całej aplikacji:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { Box(Modifier.safeDrawingPadding()) { // the rest of the app } } }
Ten fragment kodu stosuje odcięcia okna safeDrawing jako dopełnienie wokół
całej treści aplikacji. Zapewnia to, że elementy interaktywne nie
nakładają się na interfejs systemu, ale oznacza też, że żadna część aplikacji nie będzie rysowana za
interfejsem systemu, aby uzyskać efekt bez ramek. Aby w pełni wykorzystać całe okno, musisz dostosować, gdzie odcięcia są stosowane na podstawie ekranu lub komponentu.
Wszystkie te typy odcięć są automatycznie animowane za pomocą animacji IME przeniesionych do interfejsu API 21. W związku z tym wszystkie układy korzystające z tych odcięć są też automatycznie animowane, gdy zmieniają się wartości odcięć.
Istnieją 3 sposoby obsługi odcięć w celu dostosowania układów kompozycyjnych:
Modyfikatory dopełnienia
Modifier.windowInsetsPadding(windowInsets: WindowInsets) stosuje podane odcięcia okna jako dopełnienie, działając tak samo jak Modifier.padding.
Na przykład Modifier.windowInsetsPadding(WindowInsets.safeDrawing) stosuje odcięcia bezpiecznego rysowania jako dopełnienie ze wszystkich 4 stron.
Dostępnych jest też kilka wbudowanych metod narzędziowych do najczęstszych typów odcięć.
Modifier.safeDrawingPadding() to jedna z takich metod, która jest odpowiednikiem Modifier.windowInsetsPadding(WindowInsets.safeDrawing). Istnieją analogiczne modyfikatory dla innych typów odcięć.
Modyfikatory rozmiaru odcięcia
Te modyfikatory stosują ilość odcięć okna, ustawiając rozmiar komponentu na rozmiar odcięć:
Stosuje początkową stronę odcięć okna jako szerokość (podobnie jak |
|
Stosuje końcową stronę odcięć okna jako szerokość (podobnie jak |
|
Stosuje górną stronę odcięć okna jako wysokość (podobnie jak |
|
|
Stosuje dolną stronę odcięć okna jako wysokość (podobnie jak |
Te modyfikatory są szczególnie przydatne do określania rozmiaru Spacer, który zajmuje miejsce odcięć:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Zużycie odcięć
Modyfikatory dopełnienia odcięć (windowInsetsPadding i pomocnicze, takie jak safeDrawingPadding) automatycznie zużywają część odcięć, które są stosowane jako dopełnienie. Gdy przechodzisz głębiej w drzewo kompozycji, zagnieżdżone modyfikatory dopełnienia odcięć i modyfikatory rozmiaru odcięć wiedzą, że część odcięć została już zużyta przez zewnętrzne modyfikatory dopełnienia odcięć, i unikają używania tej samej części odcięć więcej niż raz, co spowodowałoby zbyt dużo dodatkowego miejsca.
Modyfikatory rozmiaru odcięć również unikają używania tej samej części odcięć więcej niż raz, jeśli odcięcia zostały już zużyte. Ponieważ jednak bezpośrednio zmieniają swój rozmiar, nie zużywają odcięć.
W rezultacie zagnieżdżanie modyfikatorów dopełnienia automatycznie zmienia ilość dopełnienia stosowanego do każdego elementu kompozycyjnego.
Patrząc na ten sam przykład LazyColumn co wcześniej, widzimy, że rozmiar LazyColumn jest zmieniany przez modyfikator imePadding. Wewnątrz LazyColumn rozmiar ostatniego elementu jest ustawiony na wysokość dolnej części pasków systemowych:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Gdy IME jest zamknięty, modyfikator imePadding() nie stosuje dopełnienia, ponieważ IME nie ma wysokości. Ponieważ modyfikator imePadding() nie stosuje dopełnienia, nie są zużywane żadne odcięcia, a wysokość Spacer będzie równa rozmiarowi dolnej części pasków systemowych.
Gdy IME się otworzy, odcięcia IME zostaną animowane, aby dopasować się do rozmiaru IME, a modyfikator imePadding() zacznie stosować dolne dopełnienie, aby zmienić rozmiar LazyColumn podczas otwierania IME. Gdy modyfikator imePadding() zacznie stosować dolne dopełnienie, zacznie też zużywać tę ilość odcięć. Dlatego wysokość Spacer zacznie się zmniejszać, ponieważ część odstępu dla pasków systemowych została już zastosowana przez modyfikator imePadding(). Gdy modyfikator imePadding() zacznie stosować dolne dopełnienie, które jest większe niż paski systemowe, wysokość Spacer wyniesie zero.
Gdy IME się zamknie, zmiany nastąpią w odwrotnej kolejności: Spacer zacznie się rozszerzać od wysokości zero, gdy imePadding() będzie stosować mniej niż dolna część pasków systemowych, aż w końcu Spacer dopasuje się do wysokości dolnej części pasków systemowych, gdy IME zostanie całkowicie animowany.
TextField.To zachowanie jest osiągane dzięki komunikacji między wszystkimi modyfikatorami windowInsetsPadding i można na nie wpływać na kilka innych sposobów.
Modifier.consumeWindowInsets(insets: WindowInsets) też zużywa odcięcia
w taki sam sposób jak Modifier.windowInsetsPadding, ale nie stosuje
zużytych odcięć jako dopełnienia. Jest to przydatne w połączeniu z modyfikatorami rozmiaru odcięcia, aby wskazać elementom równorzędnym, że pewna ilość odcięć została już zużyta:
Column(Modifier.verticalScroll(rememberScrollState())) { Spacer(Modifier.windowInsetsTopHeight(WindowInsets.systemBars)) Column( Modifier.consumeWindowInsets( WindowInsets.systemBars.only(WindowInsetsSides.Vertical) ) ) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) } Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) }
Modifier.consumeWindowInsets(paddingValues: PaddingValues) działa bardzo
podobnie do wersji z argumentem WindowInsets, ale przyjmuje dowolne PaddingValues do zużycia. Jest to przydatne do informowania elementów podrzędnych, gdy dopełnienie lub odstęp jest zapewniany przez inny mechanizm niż modyfikatory dopełnienia odcięć, np. zwykły Modifier.padding lub spacery o stałej wysokości:
Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) }
W przypadkach, gdy potrzebne są surowe odcięcia okna bez zużycia, użyj
WindowInsets wartości bezpośrednio lub użyj WindowInsets.asPaddingValues() aby
zwrócić PaddingValues odcięć, na które nie ma wpływu zużycie.
Ze względu na te zastrzeżenia zalecamy jednak, aby w miarę możliwości używać modyfikatorów dopełnienia odcięć okna i modyfikatorów rozmiaru odcięć okna.
Odcięcia i fazy Jetpack Compose
Compose używa podstawowych interfejsów API AndroidX do aktualizowania i animowania odcięć, które korzystają z podstawowych interfejsów API platformy zarządzających odcięciami. Ze względu na to zachowanie platformy odcięcia mają specjalną relację z fazami Jetpack Compose.
Wartość odcięć jest aktualizowana po fazie kompozycji, ale przed fazą układu. Oznacza to, że odczytywanie wartości odcięć w kompozycji zwykle używa wartości odcięć, która jest opóźniona o 1 klatkę. Wbudowane modyfikatory opisane na tej stronie są tak skonstruowane, aby opóźnić używanie wartości odcięć do fazy układu, co zapewnia, że wartości odcięć są używane w tej samej klatce, w której są aktualizowane.