W przypadku urządzeń składanych w pozycji na stole pojedynczy ekran jest dzielony na 2 obszary wyświetlania oddzielone fizycznym zgięciem (lub zawiasem). W pozycji na stole główna zawartość aplikacji (np. odtwarzacz wideo lub obszar gry) znajduje się w górnej połowie, a elementy interaktywne (np. elementy sterujące multimediami lub pady) – w dolnej.
Sprawdzone metody
Aby dodać do aplikacji obsługę pozycji na stole, użyj interfejsu Grid API, aby zdefiniować układ z 2 wierszami i 1 kolumną, i zastosuj zapytanie o media dotyczące pozycji na stole.
- Reagowanie na pozycję na stole: użyj elementu
mediaQuery, aby obserwować stan urządzenia. Gdy urządzenie jest złożone w pozycji na stole (windowPosture == Posture.Tabletop), możesz dynamicznie zmieniać układ bez konieczności ponownego uruchamiania aktywności lub złożonej obsługi cyklu życia. - Struktura układów za pomocą
Grid: w pozycji na stole użyj interfejsuGridAPI (2 rows,1 column), aby wyraźnie oddzielić główną zawartość wizualną w górnym wierszu nad zgięciem od elementów sterujących w dolnym wierszu pod zgięciem. - Wykorzystanie domyślnego indeksowania Z w przypadku nakładek: w standardowych pozycjach (innych niż na stole) przypisz do tej samej komórki kilka identyfikatorów obszarów, aby nałożyć elementy sterujące na odtwarzacz.
Gridautomatycznie renderuje elementy od tyłu do przodu w kolejności ich deklaracji. - Płynne przejścia: zadbaj o to, aby stan i pozycje przewijania były zachowywane podczas przechodzenia między standardowymi układami pełnoekranowymi a pozycją na stole.
Składniki
Grid: adaptacyjny kontener układu, który umożliwia umieszczanie elementów w konfigurowalnych wierszach i kolumnach. Idealnie nadaje się do dzielenia treści na różne obszary ekranu.mediaQuery: interfejs Jetpack Compose API służący do bezpośredniego sprawdzania w elementach kompozycyjnych bieżącej pozycji okna aplikacji, klas rozmiarów i charakterystyki sprzętu.
Kroki
Sprawdź stan zabezpieczeń urządzenia za pomocą mediaQuery(). Gdy urządzenie jest w pozycji na stole, ułóż zawartość aplikacji w siatce pionowej z 2 wierszami i 1 kolumną, tak aby główna zawartość znajdowała się u góry, a elementy sterujące były dostępne u dołu.
1. Określ konfiguracje siatki w trybie na stole
W funkcji typu „composable” zdefiniuj identyfikatory obszarów układu za pomocą typu wyliczeniowego i skonfiguruj bloki GridConfigurationScope dla pozycji domyślnej i na stole.
W defaultConfig oba obszary są przypisane do tej samej komórki (row = 1, column = 1). Grid używa domyślnego indeksowania Z, w którym elementy kompozycyjne zadeklarowane później w układzie są renderowane na wierzchu wcześniejszych, co pozwala kontrolerowi nakładać się na odtwarzacz bez dodatkowego zagnieżdżania kontenerów (więcej informacji znajdziesz w artykule Nakładanie elementów interfejsu za pomocą siatki).
enum class VideoPlayerArea { Player, Controller } object PlayerGridConfig { // Default: Single area layout with overlay (controls on top of player) val defaultConfig: GridConfigurationScope.() -> Unit = { row(1f) column(1f) area(areaId = VideoPlayerArea.Player, row = 1, column = 1) area(areaId = VideoPlayerArea.Controller, row = 1, column = 1) } // Tabletop: Two rows splitting content across the fold val tabletopConfig: GridConfigurationScope.() -> Unit = { row(0.5f) row(0.5f) column(1f) area(areaId = VideoPlayerArea.Player, row = 1, column = 1) // Top half above fold area(areaId = VideoPlayerArea.Controller, row = 2, column = 1) // Bottom half below fold } }
2. Wykryj pozycję na stole i zastosuj konfigurację do siatki
Użyj mediaQuery, aby wybrać aktywną konfigurację na podstawie windowPosture, przekaż config do Grid i powiąż zawartość kompozycyjną z identyfikatorami obszarów. Zadeklarowanie VideoPlayerArea.Player przed VideoPlayerArea.Controller sprawia, że gdy oba elementy współdzielą komórkę w defaultConfig, elementy sterujące są renderowane nad odtwarzaczem:
val config = mediaQuery { when (windowPosture) { Posture.Tabletop -> PlayerGridConfig.tabletopConfig else -> PlayerGridConfig.defaultConfig } } Grid(config = config) { Box( modifier = Modifier .gridItem(areaId = VideoPlayerArea.Player) ) { // VideoPlayerContent } Box( modifier = Modifier .gridItem(areaId = VideoPlayerArea.Controller) ) { // PlaybackControlsContent } }
Wyniki
Dzięki połączeniu mediaQuery i Grid aplikacja dynamicznie wykrywa, kiedy urządzenie składane jest częściowo złożone w pozycji na stole, i automatycznie dostosowuje interfejs do 2 obszarów wyświetlania oddzielonych zgięciem.
Dodatkowe materiały
- Pierwsze kroki z aplikacjami adaptacyjnymi
- Obsługa trybów wyświetlania na urządzeniach składanych
- Nakładanie elementów interfejsu za pomocą siatki