แอปควรทำงานได้ดีในอุปกรณ์ Wear OS ทุกขนาด โดยใช้ประโยชน์จากพื้นที่เพิ่มเติมที่มีอยู่ และยังคงดูดีบนหน้าจอขนาดเล็กด้วย คู่มือนี้มีคำแนะนำในการสร้างประสบการณ์ของผู้ใช้ดังกล่าว
ดูข้อมูลเพิ่มเติมเกี่ยวกับหลักการออกแบบสำหรับเลย์เอาต์แบบปรับอัตโนมัติได้ที่คำแนะนำด้านการออกแบบ
สร้างเลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์โดยใช้ Material 3
เลย์เอาต์ควรมีระยะขอบตามเปอร์เซ็นต์ ใน Wear Compose Material 3,ScreenScaffold จะคำนวณระยะห่างจากขอบตามเปอร์เซ็นต์โดยอัตโนมัติและส่ง
contentPadding ไปยัง Lambda ของเนื้อหา โดยส่งพารามิเตอร์ contentPadding นี้ไปยัง
TransformingLazyColumn
ข้อมูลโค้ดต่อไปนี้ใช้คอมโพเนนต์ TransformingLazyColumn เพื่อสร้างเนื้อหาที่ดูดีบนหน้าจอ Wear OS ขนาดต่างๆ
val columnState = rememberTransformingLazyColumnState() val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding ) { item { ListHeader( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding), transformation = SurfaceTransformation(transformationSpec) ) { Text(text = "Header") } } // ... other items item { Button( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding), transformation = SurfaceTransformation(transformationSpec), onClick = { /* ... */ }, icon = { Icon( imageVector = Icons.Default.Build, contentDescription = "build", ) }, ) { Text( text = "Build", maxLines = 1, overflow = TextOverflow.Ellipsis, ) } } } }
ตัวอย่างนี้ยังแสดง ScreenScaffold และ AppScaffold ด้วย
ซึ่งจะประสานงานระหว่างแอปกับหน้าจอแต่ละหน้า (เส้นทางการนำทาง) เพื่อให้แน่ใจว่าลักษณะการเลื่อนและการวางตำแหน่ง TimeText ถูกต้อง
สำหรับระยะห่างจากขอบด้านบนและด้านล่าง โปรดคำนึงถึงสิ่งต่อไปนี้ด้วย
- การใช้
Modifier.minimumVerticalContentPadding(เช่นListHeaderDefaults.minimumTopListContentPaddingและButtonDefaults.minimumVerticalListContentPadding) เพื่อให้TransformingLazyColumnใช้ระยะห่างจากขอบด้านบนและด้านล่างที่แนะนำเป็นอย่างน้อยเมื่อรายการเหล่านั้นปรากฏที่ขอบของรายการ - การใช้
ListHeaderสำหรับรายการแรกในลิสต์ แทนที่จะใช้ ComposableTextแบบธรรมดา
ดูข้อกำหนดทั้งหมดได้ในชุดการออกแบบ Figma ดูรายละเอียดและตัวอย่างเพิ่มเติมได้ที่หัวข้อต่อไปนี้
- ไลบรารี Horologist - มีตัวช่วยในการสร้างแอปที่เพิ่มประสิทธิภาพและแตกต่างสำหรับ Wear OS
- ตัวอย่าง ComposeStarter - ตัวอย่างที่แสดงหลักการที่ระบุไว้ในคู่มือนี้
- ตัวอย่าง JetCaster - ตัวอย่างที่ซับซ้อนมากขึ้นในการสร้างแอปให้ทำงานกับหน้าจอขนาดต่างๆ โดยใช้ไลบรารี Horologist
ใช้เลย์เอาต์แบบเลื่อนในแอป
ใช้เลย์เอาต์แบบเลื่อนได้ตามที่แสดงไว้ก่อนหน้านี้ในหน้านี้เป็นตัวเลือกเริ่มต้นเมื่อใช้หน้าจอ ซึ่งจะช่วยให้ผู้ใช้เข้าถึงคอมโพเนนต์ของแอปได้ไม่ว่าจะใช้ค่ากำหนดการแสดงผลหรือขนาดหน้าจออุปกรณ์ Wear OS แบบใดก็ตาม
ผลกระทบของขนาดอุปกรณ์และการปรับขนาดแบบอักษรที่แตกต่างกัน
กล่องโต้ตอบ
นอกจากนี้ กล่องโต้ตอบควรเลื่อนได้ เว้นแต่จะมีเหตุผลที่ดีมากที่ไม่ควรเลื่อน
คอมโพเนนต์ AlertDialog จะปรับเปลี่ยนตามอุปกรณ์และเลื่อนได้โดยค่าเริ่มต้นหากเนื้อหามีความสูงเกินวิวพอร์ต
หน้าจอที่กำหนดเองอาจต้องใช้เลย์เอาต์แบบไม่เลื่อน
หน้าจอบางหน้าอาจยังเหมาะกับเลย์เอาต์แบบไม่เลื่อน ตัวอย่างเช่น หน้าจอเพลเยอร์หลักในแอปสื่อและหน้าจอการออกกำลังกายในแอปฟิตเนส
ในกรณีเหล่านี้ ให้ดูคำแนะนำ Canonical ที่ระบุไว้ในชุดการออกแบบ 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 ขนาดต่างๆ ได้ ใช้ทั้งคำจำกัดความของตัวอย่างอุปกรณ์และการปรับขนาดแบบอักษรเพื่อดูสิ่งต่อไปนี้
- หน้าจอของคุณมีลักษณะอย่างไรเมื่อปรับขนาดเป็นค่าสูงสุด เช่น แบบอักษรขนาดใหญ่ที่สุดที่จับคู่กับหน้าจอขนาดเล็กที่สุด
- ลักษณะการทำงานของประสบการณ์การใช้งานที่แตกต่างกันในเบรกพอยต์ต่างๆ
ตรวจสอบว่าคุณใช้ WearPreviewDevices และ WearPreviewFontScales เพื่อแสดงตัวอย่างหน้าจอทั้งหมดในแอป ดูรายละเอียดทั้งหมดเกี่ยวกับการกำหนดค่าตัวอย่าง Wear OS, ข้อมูลจำเพาะของฮาร์ดแวร์ที่กำหนดเอง และการแสดงตัวอย่างรายการที่เลื่อนได้ที่หัวข้อแสดงตัวอย่าง UI ใน Compose สำหรับ Wear OS
@WearPreviewDevices @WearPreviewFontScales @Composable fun ComposeListPreview() { ComposeList() }
การทดสอบภาพหน้าจอ
นอกเหนือจากการทดสอบตัวอย่างแล้ว การทดสอบภาพหน้าจอยังช่วยให้คุณทดสอบกับขนาดฮาร์ดแวร์ที่มีอยู่ได้หลากหลาย ซึ่งจะเป็นประโยชน์อย่างยิ่งในกรณีที่คุณอาจไม่มีอุปกรณ์เหล่านั้นพร้อมใช้งานในทันที และปัญหาอาจไม่ปรากฏในหน้าจอขนาดอื่นๆ
การทดสอบภาพหน้าจอยังช่วยให้คุณระบุการถดถอยในตำแหน่งที่เฉพาะเจาะจงในฐานของโค้ดได้ด้วย
ตัวอย่างของเราใช้ Roborazzi สำหรับการทดสอบภาพหน้าจอ ดังนี้
- กำหนดค่าไฟล์โปรเจ็กต์และแอป
build.gradleเพื่อใช้ Roborazzi - สร้างการทดสอบภาพหน้าจอสำหรับแต่ละหน้าจอที่คุณมีในแอป เช่น โค้ดต่อไปนี้แสดงการทดสอบภาพหน้าจอสำหรับหน้าจอที่มีรายการ
@RunWith(ParameterizedRobolectricTestRunner::class) class ComposeListScreenTest( override val device: WearDevice ) : WearScreenshotTest() { override val tolerance = 0.02f @Test fun myScreenTest() = runTest { AppScaffold { ComposeList() } } companion object { @JvmStatic @ParameterizedRobolectricTestRunner.Parameters fun devices() = WearDevice.entries } }
ประเด็นสำคัญที่ควรทราบมีดังนี้
WearDevice.entriesมีคำจำกัดความสำหรับอุปกรณ์ Wear OS ยอดนิยมส่วนใหญ่เพื่อให้การทดสอบทำงานบนขนาดหน้าจอที่หลากหลายซึ่งเป็นตัวแทนของอุปกรณ์ทั้งหมด
สร้างรูปภาพสีทอง
หากต้องการสร้างรูปภาพสำหรับหน้าจอ ให้เรียกใช้คำสั่งต่อไปนี้ในเทอร์มินัล
./gradlew recordRoborazziDebug
ยืนยันรูปภาพ
หากต้องการยืนยันการเปลี่ยนแปลงกับรูปภาพที่มีอยู่ ให้เรียกใช้คำสั่งต่อไปนี้ในเทอร์มินัล
./gradlew verifyRoborazziDebug
ดูตัวอย่างการทดสอบภาพหน้าจอแบบเต็มได้ที่ตัวอย่าง ComposeStarter