พัฒนาให้เหมาะกับหน้าจอขนาดต่างๆ


แอปควรทำงานได้ดีในอุปกรณ์ 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 สำหรับรายการแรกในลิสต์ แทนที่จะใช้ Composable Text แบบธรรมดา

ดูข้อกำหนดทั้งหมดได้ในชุดการออกแบบ 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 สำหรับการทดสอบภาพหน้าจอ ดังนี้

  1. กำหนดค่าไฟล์โปรเจ็กต์และแอป build.gradle เพื่อใช้ Roborazzi
  2. สร้างการทดสอบภาพหน้าจอสำหรับแต่ละหน้าจอที่คุณมีในแอป เช่น โค้ดต่อไปนี้แสดงการทดสอบภาพหน้าจอสำหรับหน้าจอที่มีรายการ
@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