ตัวอย่าง Compose ใน Android Studio ช่วยให้คุณตรวจสอบและยืนยัน Composable ของ Wear OS ในขนาดจอแสดงผลของนาฬิกา ขอบกลม และการปรับขนาดแบบอักษร ต่างๆ ได้โดยตรงใน IDE โดยไม่ต้องติดตั้งใช้งานแอปในนาฬิกาจริงหรือ โปรแกรมจำลอง
เนื่องจากอุปกรณ์ Wear OS มีจอแสดงผลแบบวงกลมที่มุมจะตัดเนื้อหา
และภาพซ้อนทับของระบบ เช่น TimeText และ ScrollIndicator จะโค้งไปตาม
ขอบหน้าจอ การกำหนดค่าตัวอย่างสำหรับ Wear OS โดยเฉพาะจึงจำเป็นอย่างยิ่งต่อการ
ตรวจพบปัญหาเกี่ยวกับเลย์เอาต์ตั้งแต่เนิ่นๆ
ตั้งค่าการอ้างอิงของเวอร์ชันตัวอย่าง
หากต้องการใช้คำอธิบายประกอบตัวอย่าง Wear OS Compose และคำจำกัดความของอุปกรณ์ ให้เพิ่มทรัพยากร Dependency ต่อไปนี้ลงในไฟล์ 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)
เมื่อดูตัวอย่างทั้งหน้าจอ ให้ห่อหุ้ม Composable ของหน้าจอในทั้ง
AppScaffold และ ScreenScaffold เสมอโดยใช้คำอธิบายประกอบตัวอย่างอุปกรณ์ Wear ซึ่งจะ
แสดงผลนาฬิกาทรงกลมและช่วยให้มั่นใจได้ว่า
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 |
1 ตัวอย่างบน WearDevices.SMALL_ROUND (192x192dp) |
การทำซ้ำอย่างรวดเร็วในขนาดการแสดงผลแบบวงกลมที่มีข้อจำกัดมากที่สุด |
@WearPreviewLargeRound |
ตัวอย่าง 1 รายการใน WearDevices.LARGE_ROUND (227x227dp) |
การตรวจสอบความหนาแน่นของเลย์เอาต์และการเว้นวรรคเพิ่มเติมในนาฬิกาขนาดใหญ่ |
@WearPreviewDevices |
ตัวอย่าง 2 รายการ: SMALL_ROUND และ LARGE_ROUND |
การตรวจสอบแบบหลายอุปกรณ์มาตรฐานสำหรับ Composable ทุกหน้าจอ |
@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 มี
รหัสอุปกรณ์มาตรฐานดังนี้
WearDevices.SMALL_ROUND("id:wearos_small_round", 192x192dp)WearDevices.LARGE_ROUND("id:wearos_large_round", 227x227dp)
หากต้องการแสดงตัวอย่างบนจอแสดงผลทรงกลมขนาดใหญ่พิเศษ (เช่น นาฬิกาขนาด 44 มม.-45 มม. หรือรุ่น Ultra
ที่ 240x240dp) ให้ส่ง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. Standard Large Round
2. กลมเล็กมาก (แบบอักษรใหญ่ที่สุด + เยอรมัน)
ดูตัวอย่างคอลัมน์ที่เลื่อนได้ (TransformingLazyColumn)
โดยค่าเริ่มต้น TransformingLazyColumn จะเริ่มต้นด้วยรายการแรก
(index = 0) ที่ปักหมุดไว้ที่ด้านบนของหน้าจอ อย่างไรก็ตาม ใน Wear OS รายการต่างๆ จะ
เปลี่ยนความสูงและมุมโค้ง (SurfaceTransformation) เมื่อ
เข้าใกล้ขอบโค้งด้านบนและด้านล่างของหน้าจอ และ EdgeButton
จะปรากฏเมื่อเลื่อนไปที่ด้านล่างเท่านั้น
วิธีดูตัวอย่างลักษณะของรายการเมื่อเลื่อนลงมาครึ่งทางหรือที่ด้านล่างของรายการ
ขั้นตอนที่ 1: ยก TransformingLazyColumnState ใน Composable ของหน้าจอ
อนุญาตให้ Composable ของหน้าจอรับ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: ส่งinitialAnchorItemIndex@Preview
rememberTransformingLazyColumnStateยอมรับพารามิเตอร์การเลื่อนเริ่มต้นที่ไม่บังคับ 2 รายการ
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 ขยาย)
เคล็ดลับ: คุณยังคลิกเริ่มโหมดอินเทอร์แอกทีฟใน
@Previewใน Android Studio เพื่อเลื่อนTransformingLazyColumnแบบเรียลไทม์ด้วยเมาส์หรือ แทร็กแพด และตรวจสอบSurfaceTransformationการมอร์ฟEdgeButtonภาพเคลื่อนไหวตอนเข้า และScrollIndicatorการเคลื่อนไหวแบบเรียลไทม์ได้ด้วย
การ์ด ScrollIndicator ระหว่างการจับภาพแบบเลื่อน (LocalScrollCaptureInProgress)
เมื่อเครื่องมือจับภาพการเลื่อนของระบบ (ภาพหน้าจอแบบยาว) หรือการทดสอบภาพหน้าจอแบบหลายเฟรม
จะจับภาพการเลื่อน TransformingLazyColumn ให้สร้างชุด LocalScrollCaptureInProgress.current เป็น true ขณะจับภาพและต่อภาพ
หลายๆ ช่องมองภาพในแนวตั้ง
เนื่องจาก ScreenScaffold ไม่ซ่อน scrollIndicator
โดยอัตโนมัติในระหว่างการจับภาพการเลื่อน แถบเลื่อนแบบลอยจึงจะปรากฏซ้ำใน
ทุกช่องที่ต่อกันของภาพหน้าจอยาว เว้นแต่คุณจะป้องกันอย่างชัดเจนด้วย
!LocalScrollCaptureInProgress.current
ScreenScaffold( scrollState = columnState, scrollIndicator = { if (!LocalScrollCaptureInProgress.current) { ScrollIndicator(state = columnState) } } ) { contentPadding -> // TransformingLazyColumn content... // ... }