透過 Android Studio Compose 預覽功能,您可以在 IDE 中直接檢查及驗證不同手錶螢幕大小、圓形邊框和字型比例的 Wear OS 可組合函式,不必將應用程式部署到實體手錶或模擬器。
由於 Wear OS 裝置採用圓形螢幕,因此內容會遭到裁剪,且 TimeText 和 ScrollIndicator 等系統重疊元素會沿著螢幕邊緣彎曲,因此請務必為 Wear OS 專門設定預覽畫面,以便及早發現版面配置問題。
設定預覽依附元件
如要使用 Wear OS Compose 預覽註解和裝置定義,請將下列依附元件新增至模組的 build.gradle.kts 檔案:
dependencies {
// Provides @WearPreview* multipreview annotations
// (such as @WearPreviewDevices and @WearPreviewFontScales)
implementation("androidx.wear.compose:compose-ui-tooling:1.7.0")
// Provides WearDevices constants
// (such as WearDevices.SMALL_ROUND and WearDevices.LARGE_ROUND)
implementation("androidx.wear:wear-tooling-preview:1.0.0")
// Standard Compose preview support and interactive/animation inspection
implementation("androidx.compose.ui:ui-tooling-preview")
debugImplementation("androidx.compose.ui:ui-tooling")
}
選擇要預覽的內容:畫面或元件
預覽設定方式取決於您要預覽全螢幕還是獨立的 UI 元件。
預覽全螢幕 (AppScaffold + ScreenScaffold)
預覽整個畫面時,請務必使用 Wear 裝置預覽註解,將畫面可組合項包裝在 AppScaffold 和 ScreenScaffold 中。這會算繪圓形手錶螢幕,並確保:
TimeText會在錶面的頂端彎曲邊緣算繪。ScrollIndicator會顯示在右側邊框。EdgeButton位於正確位置,並夾在底部弧形處。- 內容邊框間距和圓形螢幕剪輯效果可如實反映實際的手錶硬體。
@WearPreviewDevices @Composable fun WorkoutScreenPreview() { MaterialTheme { // AppScaffold provides the top-level TimeText overlay AppScaffold { // WorkoutScreen contains its own ScreenScaffold and content WorkoutScreen( heartRate = 142, elapsedTime = "12:45" ) } } }
小圓形 (192x192dp)
大圓形 (227x227dp)
預覽獨立元件
預覽個別元件 (例如自訂 Card、Button 或狀態方塊) 時,請省略 device 參數,並使用深色背景的標準 @Preview。這可確保 Wear Material 3 的顏色和對比度正確顯示,不必完整呈現圓形錶面:
@Preview( showBackground = true, backgroundColor = 0xFF000000 ) @Composable fun HeartRateCardPreview() { MaterialTheme { HeartRateCard(bpm = 142, zone = "Aerobic") } }
獨立元件預覽 (不含裝置外框)。
內建多重預覽註解
androidx.wear.compose.ui.tooling.preview 套件提供內建註解,可自動設定深色背景 (backgroundColor = 0xFF000000、showBackground = true) 和圓形智慧手錶裝置尺寸:
| 註解 | 顯示內容 | 使用時機 |
|---|---|---|
@WearPreviewSmallRound |
WearDevices.SMALL_ROUND 的 1 個預覽畫面 (192x192 dp)。 |
快速疊代最受限的圓形顯示大小。 |
@WearPreviewLargeRound |
WearDevices.LARGE_ROUND 的 1 個預覽畫面 (227x227dp)。 |
檢查較大智慧手錶的版面配置密度和額外間距。 |
@WearPreviewDevices |
2 個預覽畫面:SMALL_ROUND 和 LARGE_ROUND。 |
針對每個畫面可組合項目的標準多裝置檢查。 |
@WearPreviewFontScales |
6 種預覽畫面,適用於 SMALL_ROUND 所有 Wear 字型比例:小 (0.94f)、一般 (1.0f)、中 (1.06f)、大 (1.12f)、較大 (1.18f) 和最大 (1.24f)。 |
檢查文字換行、省略和按鈕高度擴展。 |
您可以在同一個預覽函式中堆疊 @WearPreviewDevices 和 @WearPreviewFontScales,產生完整的測試矩陣:
@WearPreviewDevices @WearPreviewFontScales @Composable fun MessageDetailScreenPreview() { MaterialTheme { AppScaffold { MessageDetailScreen( sender = "Alex", body = "Running 5 mins late!" ) } } }
自訂預覽註解和硬體規格
如要更精細地控制測試,例如測試特定硬體尺寸、長度較長的本地化字串或最差的組合,您可以直接設定 @Preview,或定義自己的自訂多重預覽註解。
可用的 WearDevices 常數和自訂硬體規格
androidx.wear.tooling.preview.devices.WearDevices 物件提供標準裝置 ID:
WearDevices.SMALL_ROUND("id:wearos_small_round",192x192dp)WearDevices.LARGE_ROUND("id:wearos_large_round",227x227dp)
如要在特大圓形螢幕上預覽 (例如 44 公釐至 45 公釐的手錶或 240x240dp 的 Ultra 機型),請將自訂 spec: 字串傳遞至 device 參數:
@Preview( name = "XL Round Watch (240dp)", device = "spec:width=240dp,height=240dp,dpi=320,isRound=true", showBackground = true, backgroundColor = 0xFF000000 ) @Composable fun WorkoutScreenXlPreview() { MaterialTheme { AppScaffold { WorkoutScreen(heartRate = 142, elapsedTime = "12:45") } } }
建立自訂多重預覽註解
如要檢查極端情況,請建立自訂多重預覽註解,將最小的圓形螢幕與最大的字型比例配對,並搭配詳細的語言代碼 (例如德文) 和標準的大型圓形螢幕:
@Preview( name = "1. Standard Large Round", group = "Layout extremes", device = WearDevices.LARGE_ROUND, backgroundColor = 0xFF000000, showBackground = true ) @Preview( name = "2. Extreme Small Round (Largest Font + German)", group = "Layout extremes", device = WearDevices.SMALL_ROUND, fontScale = 1.24f, locale = "de-rDE", backgroundColor = 0xFF000000, showBackground = true ) annotation class WearPreviewExtremes
1. 標準大圓
2. 極小圓形 (最大字型 + 德文)
預覽捲動資料欄 (TransformingLazyColumn)
根據預設,TransformingLazyColumn 會初始化,並將第一個項目 (index = 0) 固定在畫面頂端。不過,在 Wear OS 上,項目會隨著靠近螢幕頂端和底部的彎曲邊緣,改變高度和圓角 (SurfaceTransformation),且只有捲動至底部時才會顯示 EdgeButton。
如要預覽清單在部分捲動或捲動至底部時的樣子,請按照下列步驟操作:
步驟 1:在畫面可組合函式中提升 TransformingLazyColumnState
允許畫面可組合項接受 TransformingLazyColumnState 參數,並將 rememberTransformingLazyColumnState() 設為預設值:
@Composable fun InboxScreen( messages: List<Message>, columnState: TransformingLazyColumnState = rememberTransformingLazyColumnState(), ) { val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState, edgeButton = { EdgeButton(onClick = { /* Compose new */ }) { Text("New message") } } ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding, ) { items(messages.size) { index -> Card( onClick = {}, modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding( CardDefaults.minimumVerticalListContentPadding ), transformation = SurfaceTransformation(transformationSpec), ) { Text(messages[index].subject) } } } } }
步驟 2:在 @Preview 中傳遞 initialAnchorItemIndex
rememberTransformingLazyColumnState 接受兩個選用的初始捲動參數:
initialAnchorItemIndex: Int:設為非負數索引 (例如3) 時,清單會初始化,並將該項目置中顯示在智慧手錶的檢視區塊中。initialAnchorItemScrollOffset: Int:相對於置中錨定項目的選用像素偏移。
您可以建立並排預覽畫面,顯示同一
螢幕的「頂端」、「中間
(捲動)」和「底部 (EdgeButton 可見)」狀態:
@WearPreviewLargeRound @Composable fun InboxScreenTopPreview() { MaterialTheme { AppScaffold { // Default (-1): Pinned to top of list (index 0) InboxScreen(messages = sampleMessages) } } } @WearPreviewLargeRound @Composable fun InboxScreenScrolledMiddlePreview() { MaterialTheme { AppScaffold { // Centers item index 3 in the viewport, showing top/bottom item morphing InboxScreen( messages = sampleMessages, columnState = rememberTransformingLazyColumnState( initialAnchorItemIndex = 3 ) ) } } } @WearPreviewLargeRound @Composable fun InboxScreenBottomEdgeButtonPreview() { MaterialTheme { AppScaffold { // Anchors on the last item so the EdgeButton is visible at the bottom InboxScreen( messages = sampleMessages, columnState = rememberTransformingLazyColumnState( initialAnchorItemIndex = sampleMessages.lastIndex ) ) } } }
頂端 (預設 -1)
中 (initialAnchorItemIndex = 3)
底部 (EdgeButton 展開)
提示:您也可以在 Android Studio 中點選任何
@Preview的「Start Interactive Mode」,使用滑鼠或觸控板捲動TransformingLazyColumn即時檢查SurfaceTransformation變形、EdgeButton進場動畫和ScrollIndicator移動情形。
在捲動擷取期間使用 Guard ScrollIndicator (LocalScrollCaptureInProgress)
當系統的捲動擷取 (長螢幕截圖) 或多影格螢幕截圖測試工具擷取捲動 TransformingLazyColumn 時,Compose 會在擷取及垂直縫合多個檢視區塊圖塊時,將 LocalScrollCaptureInProgress.current 設為 true。
由於 ScreenScaffold 不會在捲動擷取期間自動隱藏 scrollIndicator,因此除非您使用 !LocalScrollCaptureInProgress.current 明確防護,否則浮動捲軸疊加層會重複出現在長截圖的每個拼接圖塊上:
ScreenScaffold( scrollState = columnState, scrollIndicator = { if (!LocalScrollCaptureInProgress.current) { ScrollIndicator(state = columnState) } } ) { contentPadding -> // TransformingLazyColumn content... // ... }