针对不同屏幕尺寸进行开发

您的应用应该能够在各种尺寸的 Wear OS 设备上正常运行,能够充分利用更多可用空间,并且仍能在小屏幕上获得出色的显示效果。本指南提供了一些有助于实现这一用户体验的建议。

如需详细了解自适应布局的设计原则,请参阅设计指南

使用 Horologist 构建响应式布局

布局应具有基于百分比的外边距。由于 Compose 默认使用绝对值,因此请使用 Horologist 库中的组件,该库具有以下功能:

  • 水平外边距应根据设备屏幕尺寸的百分比正确设置。
  • 顶部和底部间距设置正确。由于推荐的顶部和底部间距可能取决于所使用的组件,因此带来了特殊的挑战。例如,在列表中使用时,Chip 的间距应与 Text 组件的间距不同。
  • TimeText 外边距设置正确。

以下代码段使用 Horologist 的 ScalingLazyColumn 布局版本创建在各种 Wear OS 屏幕尺寸上都能呈现出色的内容:

import com.google.android.horologist.compose.layout.ScalingLazyColumn

val columnState = rememberResponsiveColumnState(
    contentPadding = ScalingLazyColumnDefaults.padding(
        first = ItemType.Text,
        last = ItemType.SingleButton
    )
)

ScreenScaffold(scrollState = columnState) {
    ScalingLazyColumn(
        columnState = columnState,
        modifier = Modifier.fillMaxSize()
    ) {
        item {
            ResponsiveListHeader(contentPadding = firstItemPadding()) {
                Text(text = "Header")
            }
        }
        // ... other items
        item {
            Button(...)
        }
    }
}

此示例还演示了 ScreenScaffold]3AppScaffold。 这些在应用和各个屏幕(导航路线)之间的协调,以确保滚动行为和 TimeText 定位正确无误。

对于顶部和底部内边距,另请注意以下事项:

  • 第一个和最后一个 ItemType 的规范,用于确定正确的内边距。
  • 对列表中的第一项使用 ResponsiveListHeader,因为 Text 标头不应有内边距。

如需查看完整规范,请参阅 Figma 设计套件。如需了解详情和示例,请参阅:

  • Horologist 库 - 提供了一些组件,用于帮助构建针对 Wear OS 进行了优化且独具特色的应用。
  • ComposeStarter 示例 - 该示例展示了本指南中概述的原则。
  • JetCaster 示例 - 该示例较为复杂,展示了如何使用 Horologist 库构建应用以适应不同屏幕尺寸。

在应用中使用滚动布局

在实现屏幕时,将滚动布局作为默认选择(如本页前面部分所示)。这样,无论显示偏好设置或 Wear OS 设备屏幕尺寸如何,用户都能访问应用的组件。

不同设备尺寸和字体缩放的影响

不同设备尺寸和字体缩放的效果

对话框

对话框还应该可滚动,除非有充分的理由不这样做。Horologist 提供的 ResponsiveDialog 组件添加了以下内容:

  • 默认情况下会滚动。
  • 更正了百分比形式的利润率。
  • 可在空间允许的情况下调整宽度的按钮,以提供增加的点按目标。
Horologist 中的自适应对话框行为

自适应对话框,默认提供滚动功能,以及可根据可用空间进行调整的按钮。

自定义屏幕可能需要非滚动布局

某些屏幕可能仍然适合非滚动布局。例如,媒体应用中的主播放器屏幕和健身应用中的锻炼屏幕。

在这种情况下,请查看 Figma 设计套件中提供的规范指南,并使用正确的外边距实现能够适应屏幕尺寸的设计。

通过断点提供与众不同的体验

借助更大的显示屏,您可以引入更多内容和功能。若要实现这种差异化体验,请使用屏幕尺寸断点,在屏幕尺寸超过 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 屏幕尺寸进行开发。同时使用设备和字体缩放预览定义,查看以下内容:

  • 您的屏幕如何呈现不同尺寸时的外观,例如最大字体与最小屏幕的配对。
  • 您的差异化体验在不同断点处的行为。

确保使用 WearPreviewDevicesWearPreviewFontScales 针对应用中的所有屏幕实现预览。

@WearPreviewDevices
@WearPreviewFontScales
@Composable
fun ListScreenPreview() {
    ListScreen()
}

屏幕截图测试

除了预览测试之外,屏幕截图测试可让您针对各种现有硬件尺寸进行测试。如果这些设备可能无法立即可用,并且相应问题可能不会直接出现在其他尺寸的屏幕上,这样做尤其有用。

屏幕截图测试还可帮助您确定代码库中特定位置的回归问题。

我们的示例使用 Roborazzi 进行屏幕截图测试:

  1. 配置项目应用 build.gradle 文件以使用 Roborazzi。
  2. 为应用中的每个屏幕创建屏幕截图测试。例如,在 ComposeStarter 示例中,GreetingScreen 的测试实现方式如 GreetingScreenTest 中所示:
@RunWith(ParameterizedRobolectricTestRunner::class)
class GreetingScreenTest(override val device: WearDevice) : WearScreenshotTest() {
    override val tolerance = 0.02f

    @Test
    fun greetingScreenTest() = runTest {
        AppScaffold(
            timeText = { ResponsiveTimeText(timeSource = FixedTimeSource) }
        ) {
            GreetingScreen(greetingName = "screenshot", onShowList = {})
        }
    }

    companion object {
        @JvmStatic
        @ParameterizedRobolectricTestRunner.Parameters
        fun devices() = WearDevice.entries
    }
}

请注意以下要点:

  • FixedTimeSource 可用于生成屏幕截图,其中 TimeText 不会发生变化,也不会无意中导致测试失败。
  • WearDevice.entries 包含大多数热门 Wear OS 设备的定义,以便在具有代表性的屏幕尺寸下运行测试。

生成黄金图片

如需为您的屏幕生成图片,请在终端中运行以下命令:

./gradlew recordRoborazziDebug

验证图片

如需针对现有映像验证更改,请在终端运行以下命令:

./gradlew verifyRoborazziDebug

如需查看屏幕截图测试的完整示例,请参阅 ComposeStarter 示例。