在可折叠设备上,桌面姿态会将单个屏幕拆分为两个功能性显示区域,这两个区域由物理折叠边(或铰链)分隔开来。 桌面姿态可让您将应用的主要内容(例如视频播放器或游戏画布)放置在上半部分,同时将互动元素(例如媒体控件或控制板)放置在下半部分。
最佳做法
如需为应用添加桌面模式支持,请使用 Grid API 定义一个包含两行一列的布局,并应用桌面模式窗口姿势媒体查询。
- 被动检测桌面模式:使用
mediaQuery可组合项来观察设备状态。当设备折叠成桌面姿势 (windowPosture == Posture.Tabletop) 时,动态调整布局,而无需重启 activity 或进行复杂的生命周期处理。 - 使用
Grid布局结构:在桌面模式下,使用GridAPI(2 rows、1 column)将主要视觉内容清晰地分隔到折叠上方的顶行,并将互动控件分隔到折叠下方的底行。 - 利用叠加层的隐式 z-index:在标准(非桌面)姿态下,为同一单元格分配多个区域 ID,以将控件叠加在播放器上。
Grid会按声明顺序自动从后到前渲染项。 - 提供顺畅的过渡:确保在标准全屏布局和桌面姿势之间过渡时,状态和滚动位置得以保留。
所需要素
Grid:一种自适应布局容器,可让您在可配置的行和列中放置项,非常适合将内容拆分到不同的屏幕区域。mediaQuery:一种 Jetpack Compose API,用于直接在可组合项中查询应用的当前窗口姿态、大小类别和硬件特征。
步骤
使用 mediaQuery() 查询设备姿态。当设备处于桌面折叠状态时,请将应用的内容排列成一个两行一列的垂直网格,确保主要内容位于顶部,控件位于底部且可供访问。
1. 为桌面模式定义网格配置
在可组合函数内,使用枚举定义布局区域 ID,并为默认姿势和桌面姿势设置 GridConfigurationScope 块。
在 defaultConfig 中,这两个区域都分配给同一个单元格 (row = 1, column = 1)。Grid 使用隐式 z 索引,其中布局中稍后声明的可组合项会渲染在较早声明的可组合项之上,从而允许控制器覆盖播放器,而无需额外的容器嵌套(如需了解详情,请参阅使用网格的界面元素叠加层)。
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. 检测桌上姿势并将配置应用于 Grid
使用 mediaQuery 根据 windowPosture 选择有效配置,将 config 传递给 Grid,并将可组合的内容绑定到区域 ID。在 VideoPlayerArea.Controller 之前声明 VideoPlayerArea.Player 可确保当两者在 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,您的应用可以动态检测可折叠设备何时部分折叠成桌面姿势,并自动将界面调整为由折叠边分隔的两个功能性显示区域。