可折叠设备处于桌面模式时,单个屏幕会被物理折叠边(或铰链)分隔成两个功能性显示区域。 在桌面模式下,您可以将应用的主要内容(例如视频播放器或游戏画布)放置在屏幕上半部分,而将互动元素(例如媒体控件或控制面板)放置在屏幕下半部分。
最佳做法
如需为应用添加桌面模式支持,请使用 Grid API 定义一个两行一列的布局,并应用桌面模式窗口姿态媒体查询。
- 被动检测桌面模式:使用
mediaQuery可组合项观察设备状态。当设备折叠成桌面模式 (windowPosture == Posture.Tabletop) 时,动态调整布局,无需重启 activity 或进行复杂的生命周期处理。 - 使用
Grid构建布局:在桌面模式下,使用GridAPI(2 rows、1 column)将主要视觉内容清晰地分隔到首屏上方的顶行,并将互动控件分隔到非首屏下方的底行。 - 利用隐式 Z 轴索引实现叠加层:在标准(非桌面)状态下,为同一单元格分配多个区域 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. 检测桌面模式并对网格应用配置
使用 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,您的应用可以动态检测可折叠设备何时部分折叠成桌面模式,并自动将其界面调整为由折叠边分隔的两个功能显示区域。