В настольном режиме на складных устройствах единый экран разделяется на две функциональные области, разделенные физической складкой (или шарниром). В настольном режиме основной контент приложения (например, видеопроигрыватель или игровое поле) можно разместить в верхней половине экрана, а интерактивные элементы (например, элементы управления мультимедиа или контроллеры) – в нижней.
Рекомендации
Чтобы добавить поддержку режима настольного устройства в приложение, используйте API Grid, чтобы определить макет с двумя строками и одним столбцом, и примените медиазапрос положения окна настольного устройства.
- Реактивное определение режима настольного устройства. Используйте composable-функцию
mediaQuery, чтобы отслеживать состояние устройства. Когда устройство складывается в настольный режим (windowPosture == Posture.Tabletop), динамически меняйте макет без перезапуска действий или сложной обработки жизненного цикла. - Структурируйте макеты с помощью
Grid. В настольном режиме используйте APIGrid(2 rows,1 column), чтобы разделить основной визуальный контент в верхней строке в видимой части страницы и интерактивные элементы управления в нижней строке в невидимой нижней части страницы. - Используйте неявную z-индексацию для наложений. В стандартных положениях (не в режиме ноутбука) назначьте несколько идентификаторов областей одной ячейке, чтобы наложить элементы управления на проигрыватель.
Gridавтоматически отрисовывает элементы в порядке их объявления. - Обеспечьте плавные переходы. Убедитесь, что состояние и положение прокрутки сохраняются при переходе между стандартными полноэкранными макетами и настольным режимом.
Ингредиенты
Grid– контейнер адаптивного макета, который позволяет размещать элементы в настраиваемых строках и столбцах. Идеально подходит для разделения контента по разным областям экрана.mediaQuery– API Jetpack Compose, который используется для запроса текущего положения окна приложения, классов размера и аппаратных характеристик непосредственно в composable-функциях.
Шаги
Запросите состояние устройства с помощью mediaQuery(). Когда устройство находится в настольном режиме, расположите контент приложения в вертикальной сетке с двумя строками и одним столбцом. Основной контент должен оставаться вверху, а элементы управления – внизу.
1. Как настроить сетку для настольного режима
Внутри composable-функции определите идентификаторы областей макета с помощью перечисления и настройте блоки GridConfigurationScope для стандартного и настольного режимов.
В defaultConfig обе области назначены одной ячейке (row = 1, column = 1). В Grid используется неявная z-индексация, при которой composable-функции, объявленные в макете позже, отображаются поверх предыдущих. Это позволяет контроллеру перекрывать проигрыватель без дополнительного вложения контейнеров (подробнее см. в разделе Наложение элементов интерфейса с помощью Grid).
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. Определять положение устройства на столе и применять конфигурацию к сетке
Используйте mediaQuery, чтобы выбрать активную конфигурацию на основе windowPosture, передайте config в Grid и привяжите composable-контент к идентификаторам областей. Если объявить VideoPlayerArea.Player перед VideoPlayerArea.Controller, то когда они оба будут находиться в одной ячейке в defaultConfig, элементы управления будут отображаться над проигрывателем:
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 } }
Результаты
Сочетание mediaQuery и Grid позволяет приложению динамически определять, когда складное устройство частично сложено в настольном режиме, и автоматически разделять интерфейс на две функциональные области, разделенные сгибом.
Дополнительные ресурсы
- Начало работы с адаптивными приложениями
- Поддержка режимов складного экрана
- Оверлеи элементов интерфейса с сеткой