您的应用应能够在各种尺寸的 Wear OS 设备上正常运行,并充分利用可用的额外空间,同时在小屏幕上也能呈现出出色的外观。本指南提供了实现此用户体验的建议。
如需详细了解自适应布局的设计原则,请参阅设计指南。
使用 Material 3 构建响应式布局
布局应采用基于百分比的边距。由于 Compose 默认以绝对值运作,因此请使用 Horologist 库中的rememberResponsiveColumnPadding
来计算内边距,并将其传递给 ScreenScaffold
的 contentPadding
形参和 TransformingLazyColumn
的 contentPadding
形参。
以下代码段使用 TransformingLazyColumn
组件创建在各种 Wear OS 屏幕尺寸上都看起来很棒的内容:
val columnState = rememberTransformingLazyColumnState() val contentPadding = rememberResponsiveColumnPadding( first = ColumnItemType.ListHeader, last = ColumnItemType.Button, ) val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState, contentPadding = contentPadding ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding ) { item { ListHeader( modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec), transformation = SurfaceTransformation(transformationSpec) ) { Text(text = "Header") } } // ... other items item { Button( modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec), transformation = SurfaceTransformation(transformationSpec), onClick = { /* ... */ }, icon = { Icon( imageVector = Icons.Default.Build, contentDescription = "build", ) }, ) { Text( text = "Build", maxLines = 1, overflow = TextOverflow.Ellipsis, ) } } } }
此示例还演示了 ScreenScaffold
和 AppScaffold
。这些对象在应用和各个界面(导航路线)之间进行协调,以确保正确的滚动行为和 TimeText
定位。
对于顶部和底部内边距,另请注意以下事项:
- 第一个和最后一个
ItemType
的规范,用于确定正确的内边距。 - 对列表中的第一项使用
ListHeader
,因为Text
标题不应有内边距。
如需查看完整规范,请参阅 Figma 设计套件。如需了解详情和示例,请参阅:
- Horologist 库 - 提供帮助程序,帮助您为 Wear OS 构建经过优化且具有差异化的应用。
- ComposeStarter 示例 - 此示例展示了本指南中列出的原则。
- JetCaster 示例:一个更复杂的示例,展示了如何使用 Horologist 库构建适用于不同屏幕尺寸的应用。
在应用中使用滚动布局
在实现屏幕时,请使用滚动布局(如本页面上方所示)作为默认选项。这样,无论显示偏好设置或 Wear OS 设备屏幕尺寸如何,用户都可以访问应用的组件。

不同设备尺寸和字体放大的影响。
对话框
对话框也应可滚动,除非有充分的理由不这样做。
AlertDialog
组件是自适应的,如果内容超出视口高度,则默认可滚动。
自定义屏幕可能需要非滚动布局
某些屏幕可能仍适合使用非滚动布局。一些示例包括媒体应用中的主播放器界面和健身应用中的锻炼界面。
在这些情况下,请参阅 Figma Design Kit 中提供的规范指南,并使用正确的外边距实现可根据屏幕尺寸调整的设计。
通过断点提供差异化体验
借助更大的显示屏,您可以添加更多内容和功能。如需实现这种差异化体验,请使用屏幕尺寸断点,在屏幕尺寸超过 225 dp 时显示不同的布局:
const val LARGE_DISPLAY_BREAKPOINT = 225 @Composable fun isLargeDisplay() = LocalConfiguration.current.screenWidthDp >= LARGE_DISPLAY_BREAKPOINT // ... // ... use in your Composables: if (isLargeDisplay()) { // Show additional content. } else { // Show content only for smaller displays. } // ...
设计指南中详细介绍了这些机会。
使用预览测试屏幕尺寸和字体大小的组合
Compose 预览可帮助您针对各种 Wear OS 屏幕尺寸进行开发。同时使用设备和字体放大预览定义可查看以下内容:
- 在极端尺寸下屏幕的外观,例如,最小字体与最小屏幕搭配使用。
- 您的差异化体验在不同断点上的行为方式。
确保您使用 WearPreviewDevices
和 WearPreviewFontScales
为应用中的所有屏幕实现预览。
@WearPreviewDevices @WearPreviewFontScales @Composable fun ComposeListPreview() { ComposeList() }
屏幕截图测试
除了预览测试之外,屏幕截图测试还可让您针对各种现有硬件尺寸进行测试。如果您无法立即使用这些设备,并且问题可能不会出现在其他屏幕尺寸上,这种方法特别有用。
屏幕截图测试还有助于您发现代码库中特定位置的回归问题。
我们的示例使用 Roborazzi 进行屏幕截图测试:
- 配置您的项目和应用
build.gradle
文件以使用 Roborazzi。 - 为应用中的每个屏幕创建屏幕截图测试。例如,在 ComposeStarter 示例中,实现了针对
GreetingScreen
的测试,如GreetingScreenTest
所示:
@RunWith(ParameterizedRobolectricTestRunner::class)
class GreetingScreenTest(override val device: WearDevice) : WearScreenshotTest() {
override val tolerance = 0.02f
@Test
fun greetingScreenTest() = runTest {
AppScaffold {
GreetingScreen(greetingName = "screenshot", onShowList = {})
}
}
companion object {
@JvmStatic
@ParameterizedRobolectricTestRunner.Parameters
fun devices() = WearDevice.entries
}
}
需要注意以下几点:
WearDevice.entries
包含最热门 Wear OS 设备的定义,以便在代表性范围的屏幕尺寸上运行测试。
生成黄金映像
如需为屏幕生成图片,请在终端中运行以下命令:
./gradlew recordRoborazziDebug
验证图片
如需针对现有映像验证更改,请在终端中运行以下命令:
./gradlew verifyRoborazziDebug
如需查看屏幕截图测试的完整示例,请参阅 ComposeStarter 示例。