เริ่มต้นใช้งานการ์ด


หากต้องการเริ่มแสดงไทล์จากแอป ให้รวมทรัพยากร Dependency ต่อไปนี้ไว้ในไฟล์ build.gradle ของแอป

Groovy

dependencies {
    // Use to implement support for wear tiles
    implementation "androidx.wear.tiles:tiles:1.6.0"

    // Use to utilize standard components and layouts in your tiles
    implementation "androidx.wear.protolayout:protolayout:1.4.0"

    // Use to utilize components and layouts with Material Design in your tiles
    implementation "androidx.wear.protolayout:protolayout-material:1.4.0"

    // Use to include dynamic expressions in your tiles
    implementation "androidx.wear.protolayout:protolayout-expression:1.4.0"

    // Use to preview wear tiles in your own app
    debugImplementation "androidx.wear.tiles:tiles-renderer:1.6.0"

    // Use to fetch tiles from a tile provider in your tests
    testImplementation "androidx.wear.tiles:tiles-testing:1.6.0"
}

Kotlin

dependencies {
    // Use to implement support for wear tiles
    implementation("androidx.wear.tiles:tiles:1.6.0")

    // Use to utilize standard components and layouts in your tiles
    implementation("androidx.wear.protolayout:protolayout:1.4.0")

    // Use to utilize components and layouts with Material Design in your tiles
    implementation("androidx.wear.protolayout:protolayout-material:1.4.0")

    // Use to include dynamic expressions in your tiles
    implementation("androidx.wear.protolayout:protolayout-expression:1.4.0")

    // Use to preview wear tiles in your own app
    debugImplementation("androidx.wear.tiles:tiles-renderer:1.6.0")

    // Use to fetch tiles from a tile provider in your tests
    testImplementation("androidx.wear.tiles:tiles-testing:1.6.0")
}

หัวข้อสำคัญ

ไทล์ไม่ได้สร้างขึ้นในลักษณะเดียวกับแอป Android และใช้แนวคิดที่แตกต่างกัน ดังนี้

  • เทมเพลตเลย์เอาต์: กำหนดการจัดเรียงโดยรวมขององค์ประกอบภาพบน จอแสดงผล ซึ่งทำได้โดยใช้ฟังก์ชัน primaryLayout()
  • องค์ประกอบเลย์เอาต์: แสดงองค์ประกอบกราฟิกแต่ละรายการ เช่น ปุ่มหรือการ์ด หรือองค์ประกอบดังกล่าวหลายรายการที่จัดกลุ่มเข้าด้วยกันโดยใช้คอลัมน์ buttonGroup หรือองค์ประกอบที่คล้ายกัน โดยจะฝังอยู่ในเทมเพลตเลย์เอาต์
  • ทรัพยากร: ออบเจ็กต์ ResourceBuilders.Resources ประกอบด้วยแผนที่ ของคู่คีย์-ค่าของทรัพยากร Android (รูปภาพ) ที่จำเป็นต่อการ แสดงผลเลย์เอาต์ และเวอร์ชัน
  • ไทม์ไลน์: ออบเจ็กต์ TimelineBuilders.Timeline คือรายการของอินสแตนซ์อย่างน้อย 1 รายการของออบเจ็กต์เลย์เอาต์ คุณสามารถระบุกลไกและ นิพจน์ต่างๆ เพื่อระบุเวลาที่โปรแกรมแสดงผลควรเปลี่ยนจากออบเจ็กต์เลย์เอาต์หนึ่ง ไปยังอีกออบเจ็กต์หนึ่ง เช่น เพื่อหยุดแสดงเลย์เอาต์ในเวลาที่เฉพาะเจาะจง
  • สถานะ: โครงสร้างข้อมูลประเภท StateBuilders.State ที่ส่งผ่านระหว่างไทล์กับแอป เพื่อให้คอมโพเนนต์ทั้ง 2 สื่อสารกันได้ เช่น หากมีการแตะปุ่มในไทล์ สถานะ จะมีรหัสของปุ่ม นอกจากนี้ คุณยังแลกเปลี่ยนประเภทข้อมูลโดยใช้แผนที่ได้ด้วย
  • ไทล์: ออบเจ็กต์ TileBuilders.Tile ที่แสดงไทล์ ซึ่งประกอบด้วยไทม์ไลน์ รหัสเวอร์ชันของทรัพยากร ช่วงความสดใหม่ และสถานะ
  • Protolayout: คำนี้ปรากฏในชื่อของคลาสต่างๆ ที่เกี่ยวข้องกับไทล์ และหมายถึงไลบรารี Protolayout ของ Wear OS ซึ่งเป็นไลบรารีกราฟิก ที่ใช้ในแพลตฟอร์มต่างๆ ของ Wear OS

สร้างไทล์

หากต้องการระบุไทล์จากแอป ให้ใช้บริการประเภท TileService และลงทะเบียนในไฟล์ Manifest จากนั้นระบบจะขอไทล์ที่จำเป็นระหว่างการโทรไปยัง onTileRequest() และขอทรัพยากรระหว่างการโทรไปยัง onTileResourcesRequest()

class MyTileService : TileService() {

    override fun onTileRequest(requestParams: RequestBuilders.TileRequest) =
        Futures.immediateFuture(
            Tile.Builder()
                .setResourcesVersion(RESOURCES_VERSION)
                .setTileTimeline(
                    Timeline.fromLayoutElement(
                        materialScope(this, requestParams.deviceConfiguration) {
                            primaryLayout(
                                mainSlot = {
                                    text("Hello, World!".layoutString, typography = BODY_LARGE)
                                }
                            )
                        }
                    )
                )
                .build()
        )

    override fun onTileResourcesRequest(requestParams: ResourcesRequest) =
        Futures.immediateFuture(Resources.Builder().setVersion(RESOURCES_VERSION).build())
}

จากนั้นเพิ่มบริการภายในแท็ก <application> ของไฟล์ AndroidManifest.xml

<service
    android:name=".snippets.m3.tile.MyTileService"
    android:label="@string/tile_label"
    android:description="@string/tile_description"
    android:icon="@mipmap/ic_launcher"
    android:exported="true"
    android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">
    <intent-filter>
        <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" />
    </intent-filter>

    <meta-data android:name="androidx.wear.tiles.PREVIEW"
        android:resource="@drawable/tile_preview" />
</service>

ตัวกรองสิทธิ์และเจตนาจะลงทะเบียนบริการนี้เป็นผู้ให้บริการไทล์

ระบบจะแสดงไอคอน ป้ายกำกับ คำอธิบาย และแหล่งข้อมูลตัวอย่างต่อผู้ใช้เมื่อ ผู้ใช้กำหนดค่าไทล์ในโทรศัพท์หรือนาฬิกา โปรดทราบว่าทรัพยากรตัวอย่าง รองรับตัวระบุทรัพยากรมาตรฐานทั้งหมดของ Android จึงสามารถ ปรับเปลี่ยนตัวอย่างตามปัจจัยต่างๆ เช่น ขนาดหน้าจอและภาษาของอุปกรณ์ได้ ดูคำแนะนำเพิ่มเติมได้ในรายการตรวจสอบการแสดงตัวอย่าง

ติดตั้งใช้งานแอปและเพิ่มไทล์ลงในภาพหมุนของไทล์ (นอกจากนี้ยังมีวิธีแสดงตัวอย่างไทล์ที่เป็นมิตรกับนักพัฒนาแอปมากขึ้นด้วย แต่ตอนนี้ให้ทำด้วยตนเองก่อน)

การ์ด Wear OS ที่สร้างด้วย Material 3 ซึ่งแสดงข้อความ &quot;Hello World&quot;
รูปที่ 1 ไทล์ "Hello World"

ดูตัวอย่างที่สมบูรณ์ได้ในตัวอย่างโค้ดใน GitHub หรือโค้ดแล็บ

สร้าง UI สำหรับไทล์

องค์ประกอบ UI ที่สื่ออารมณ์ของ Material 3 สร้างขึ้นโดยใช้แนวทางที่มีโครงสร้าง ซึ่งขับเคลื่อนโดยรูปแบบตัวสร้างที่ปลอดภัยต่อประเภทของ Kotlin

การจัดวาง

ดูคำแนะนำเกี่ยวกับหลักการออกแบบที่อยู่เบื้องหลังการสร้างเลย์เอาต์การ์ดที่มีประสิทธิภาพและตอบสนองได้ดีได้ที่เลย์เอาต์ทั่วไปสำหรับการ์ด

หากต้องการสร้างเลย์เอาต์ ให้ทำดังนี้

  1. เริ่มต้นขอบเขต Material Design: เรียกใช้ฟังก์ชัน materialScope() โดยระบุ context และ deviceConfiguration ที่จำเป็น คุณ สามารถใส่พารามิเตอร์ที่ไม่บังคับ เช่น allowDynamicTheme และ defaultColorScheme allowDynamicTheme จะเป็น true โดยค่าเริ่มต้น และ defaultColorScheme จะแสดงถึงColorScheme ที่ใช้เมื่อสีแบบไดนามิก ไม่พร้อมใช้งาน เช่น เมื่อผู้ใช้ปิดฟีเจอร์นี้ หรือ เมื่ออุปกรณ์ไม่รองรับ หรือ allowDynamicTheme เป็น false)

  2. สร้าง UI ภายในขอบเขต: คอมโพเนนต์ UI ทั้งหมดสำหรับเลย์เอาต์ไทล์ที่กำหนด ต้องกำหนดภายใน Lambda ของการเรียก materialScope() ระดับบนสุดรายการเดียว ฟังก์ชันคอมโพเนนต์เหล่านี้ เช่น primaryLayout() และ textEdgeButton() เป็นฟังก์ชันส่วนขยายใน MaterialScope และจะใช้ได้ก็ต่อเมื่อมีการเรียกใช้ในขอบเขตของตัวรับนี้เท่านั้น

    materialScope(
        context = context,
        deviceConfiguration =
        requestParams.deviceConfiguration, // requestParams is passed to onTileRequest
        defaultColorScheme = myFallbackColorScheme
    ) {
        // inside the MaterialScope, you can call functions like primaryLayout()
        primaryLayout(
            titleSlot = { text(text = "Title".layoutString) },
            mainSlot = { text(text = "Main Content".layoutString) },
            bottomSlot = {
                textEdgeButton(
                    labelContent = { text("Action".layoutString) },
                    onClick = clickable()
                )
            }
        )
    }

สล็อต

ใน M3 เลย์เอาต์ไทล์จะใช้แนวทางที่ได้แรงบันดาลใจจาก Compose ซึ่งใช้ช่องที่แตกต่างกัน 3 ช่อง โดยมีรายการต่อไปนี้จากบนลงล่าง

  1. titleSlot โดยปกติจะใช้กับชื่อหรือส่วนหัวหลัก
  2. mainSlotสำหรับเนื้อหาหลัก
  3. bottomSlot ซึ่งมักใช้สำหรับการดำเนินการหรือข้อมูลเพิ่มเติม นอกจากนี้ ปุ่มขอบจะปรากฏที่นี่ด้วย
เลย์เอาต์การ์ดที่แสดง titleSlot, mainSlot และ bottomSlot
รูปที่ 2. titleSlot, mainSlot และ bottomSlot

เนื้อหาของแต่ละช่องมีดังนี้

  • titleSlot (ไม่บังคับ): โดยปกติจะเป็นคำ 2-3 คำที่ text() สร้างขึ้น
  • mainSlot (ต้องระบุ): คอมโพเนนต์ที่จัดระเบียบเป็นโครงสร้าง เช่น แถว คอลัมน์ และกลุ่มปุ่ม นอกจากนี้ คอมโพเนนต์เหล่านี้ยังฝังซ้อนกันได้ด้วย เช่น คอลัมน์อาจมีแถว
  • bottomSlot (ไม่บังคับ): โดยปกติจะใส่ปุ่ม ที่ติดขอบหรือป้ายกำกับข้อความ

เนื่องจากเลื่อนไทล์ไม่ได้ จึงไม่มีคอมโพเนนต์สำหรับการแบ่งหน้า การเลื่อน หรือการจัดการรายการเนื้อหาที่ยาว โปรดตรวจสอบว่าเนื้อหายังคงมองเห็นได้เมื่อขนาดแบบอักษรเพิ่มขึ้นหรือข้อความยาวขึ้นเนื่องจากการแปล

คอมโพเนนต์ UI

ไลบรารี protolayout-material3 มีคอมโพเนนต์จำนวนมาก ซึ่งออกแบบตามข้อกำหนดเฉพาะของ Material 3 Expressive และคำแนะนำเกี่ยวกับอินเทอร์เฟซผู้ใช้

ปุ่ม

ปุ่มส่วนใหญ่มุ่งเน้นการดำเนินการ โดยมีไว้เพื่อทริกเกอร์การดำเนินการที่เฉพาะเจาะจง เนื้อหาของปุ่มแต่ละปุ่ม เช่น ไอคอนหรือข้อความสั้นๆ จะระบุ การดำเนินการ

  • textButton(): ปุ่มที่มีช่องเดียวสำหรับเนื้อหาข้อความ (สั้น)
  • iconButton(): ปุ่มที่มีช่องเดียวเพื่อแสดงไอคอน
  • avatarButton(): ปุ่มรูปโปรไฟล์ทรงแคปซูลที่มีช่องสูงสุด 3 ช่องสำหรับใส่เนื้อหาที่แสดงป้ายกำกับและป้ายกำกับรองที่ซ้อนกันในแนวตั้ง รวมถึงรูปภาพ (รูปโปรไฟล์) ที่อยู่ข้างๆ
  • imageButton(): ปุ่มรูปภาพที่คลิกได้ซึ่งไม่มีช่องเพิ่มเติม มีเพียงรูปภาพ (เช่น backgroundImage เป็นพื้นหลัง)
  • compactButton(): ปุ่มขนาดกะทัดรัดที่มีช่องสูงสุด 2 ช่องสำหรับวาง เนื้อหาที่ซ้อนกันในแนวนอนซึ่งแสดงไอคอนและข้อความข้างๆ
  • button(): ปุ่มรูปแคปซูลที่มีช่องสูงสุด 3 ช่องสำหรับใส่ เนื้อหาที่แสดงป้ายกำกับและป้ายกำกับรองที่ซ้อนกันในแนวตั้ง รวมถึง ไอคอนข้างป้ายกำกับ

ปุ่มขอบ

ปุ่มขอบเป็นปุ่มแบบเต็มความกว้างเฉพาะทางที่ยึดไว้ที่ด้านล่างของหน้าจอกลมของนาฬิกา ซึ่งแสดงการดำเนินการที่สำคัญที่สุดที่ต้องทำจากหน้าจอกระเบื้องปัจจุบัน

  • iconEdgeButton(): ปุ่มขอบที่มีช่องเดียวสำหรับใส่ไอคอนหรือเนื้อหาขนาดเล็กที่มีลักษณะกลมคล้ายกัน
  • textEdgeButton(): ปุ่มขอบที่ให้ช่องเดียวสำหรับใส่ข้อความหรือเนื้อหาที่ยาวและกว้างคล้ายกัน

การ์ด

การ์ดส่วนใหญ่เน้นข้อมูล โดยจะแสดงคอลเล็กชันของ Structured Data ที่เกี่ยวข้อง แม้ว่าคุณจะสร้างการ์ดแบบอินเทอร์แอกทีฟได้ แต่โดยปกติแล้วการ์ดจะ แสดงข้อมูลสรุป ซึ่งผู้ใช้สามารถแตะเพื่อดูรายละเอียดเพิ่มเติม หรือดำเนินการที่เกี่ยวข้องได้

  • titleCard(): การ์ดไตเติ้ลที่มีช่อง 1-3 ช่อง ซึ่งมักจะเป็นข้อความ
  • appCard(): การ์ดแอปที่มีช่องสูงสุด 5 ช่อง ซึ่งมักจะเป็นข้อความ
  • textDataCard(): การ์ดข้อมูลที่แสดงช่องซ้อนกันในแนวตั้งได้สูงสุด 3 ช่อง โดยปกติจะเป็นข้อความหรือตัวเลข
  • iconDataCard(): การ์ดข้อมูลที่มีไอคอนซึ่งมีช่องซ้อนกันในแนวตั้งสูงสุด 3 ช่อง โดยปกติจะเป็นข้อความหรือตัวเลข
  • graphicDataCard(): การ์ดข้อมูลกราฟิกที่มีช่องสำหรับข้อมูลกราฟิก เช่น ตัวบ่งชี้ความคืบหน้า และช่องที่ซ้อนกันในแนวตั้งสูงสุด 2 ช่อง ซึ่งมักใช้สำหรับคำอธิบายข้อความ

ตัวบ่งบอกความคืบหน้า

  • circularProgressIndicator(): แสดงความคืบหน้าสู่เป้าหมายโดยใช้ องค์ประกอบรัศมี
  • segmentedCircularProgressIndicator(): แสดงความคืบหน้าสู่เป้าหมายโดยใช้องค์ประกอบรัศมีที่มีขั้นตอนที่แตกต่างกัน

องค์ประกอบเลย์เอาต์ของกลุ่ม

  • buttonGroup(): เลย์เอาต์คอมโพเนนต์ที่วางองค์ประกอบย่อยในลำดับแนวนอน
  • primaryLayout(): เลย์เอาต์แบบเต็มหน้าจอที่แสดงถึงรูปแบบเลย์เอาต์ M3 ที่แนะนำซึ่งตอบสนองและดูแลการจัดวางองค์ประกอบ พร้อมกับระยะขอบและระยะห่างภายในที่แนะนำ

ใช้ธีม

ใน Material 3 Expressive ระบบสีจะกำหนดโดยบทบาทสีมาตรฐาน 29 บทบาท ซึ่งจัดเป็น 6 กลุ่ม ได้แก่ สีปฐมภูมิ สีทุติยภูมิ สีตติยภูมิ สีข้อผิดพลาด สีพื้นผิว และสีเส้นขอบ

ระบบสี Material 3 Expressive ซึ่งแสดงบทบาทของสีที่จัดเป็นกลุ่ม เช่น สีหลัก สีรอง สีเสริม สีข้อผิดพลาด สีพื้นผิว และสีเส้นขอบ
รูปที่ 3 ระบบสี Material 3 Expressive

ColorScheme จะแมปบทบาททั้ง 29 บทบาทนี้กับสีที่เกี่ยวข้อง และเนื่องจากเป็นส่วนหนึ่งของ MaterialScope และต้องสร้างคอมโพเนนต์ภายใน MaterialScope คอมโพเนนต์จึงใช้สีจากรูปแบบโดยอัตโนมัติ วิธีนี้ช่วยให้องค์ประกอบ UI ทั้งหมดเป็นไปตามมาตรฐาน Material Design โดยอัตโนมัติ

หากต้องการให้ผู้ใช้เลือกระหว่างรูปแบบสีที่คุณกำหนด เช่น รูปแบบที่แสดงถึง สีของแบรนด์ กับรูปแบบที่ระบบกำหนด ซึ่งอาจได้มาจาก หน้าปัดปัจจุบันของผู้ใช้หรือรูปแบบที่ผู้ใช้เลือก ให้เริ่มต้น MaterialScope ดังนี้

val myColorScheme =
    ColorScheme(
        primary = Color.rgb(0, 0, 255).argb, // Blue
        onPrimary = Color.rgb(255, 255, 255).argb, // White
        // 27 more
    )

materialScope(
    context = context,
    deviceConfiguration = requestParams.deviceConfiguration,
    defaultColorScheme = myColorScheme
) {
    // If the user selects "no theme" in settings, myColorScheme is used.
    // Otherwise, the system-provided theme is used.
}

หากเลือกตัวเลือกนี้ ให้ระบุไอคอนไทล์ขาวดำเพื่อให้ระบบ สามารถปรับสีได้อย่างถูกต้องเพื่อการมองเห็นที่เหมาะสมที่สุดเมื่อใช้กับธีมใดก็ตาม

หากต้องการบังคับให้หน้าต่างปรากฏในรูปแบบสีที่คุณระบุ ให้ปิดใช้การรองรับ การกำหนดธีมแบบไดนามิกโดยตั้งค่า allowDynamicTheme เป็น false

materialScope(
    context = context,
    deviceConfiguration = requestParams.deviceConfiguration,
    allowDynamicTheme = false,
    defaultColorScheme = myColorScheme
) {
    // myColorScheme is *always* used.
}

สี

คอมโพเนนต์แต่ละรายการใช้ชุดย่อยของบทบาทสี 29 บทบาทที่กำหนดโดย ColorScheme ตัวอย่างเช่น ปุ่มจะใช้สีได้สูงสุด 4 สี ซึ่งโดยค่าเริ่มต้นจะ นำมาจากกลุ่ม "หลัก" ของ ColorScheme ที่ใช้งานอยู่

โทเค็นคอมโพเนนต์ ButtonColors บทบาท ColorScheme
containerColor หลัก
iconColor onPrimary
labelColor onPrimary
secondaryLabelColor onPrimary (ความทึบแสง 0.8)

ดูคำแนะนำโดยละเอียดเกี่ยวกับการใช้สีกับการออกแบบ Wear OS ได้ที่คู่มือ การออกแบบสี

คุณอาจต้องเบี่ยงเบนจากโทเค็นสีเริ่มต้นสำหรับองค์ประกอบ UI บางอย่าง เช่น คุณอาจต้องการให้ textEdgeButton ใช้ สีจากกลุ่ม "รอง" หรือ "ลำดับที่ 3" แทน "หลัก" เพื่อให้ โดดเด่นและมีคอนทราสต์ที่ดีขึ้น

คุณปรับแต่งสีของคอมโพเนนต์ได้หลายวิธี ดังนี้

  1. ใช้ฟังก์ชันตัวช่วยสำหรับสีที่กำหนดไว้ล่วงหน้า ใช้ฟังก์ชันช่วย เช่น filledTonalButtonColors() เพื่อใช้รูปแบบปุ่มมาตรฐานสำหรับ Material 3 Expressive ฟังก์ชันเหล่านี้จะสร้างอินสแตนซ์ ButtonColors ที่กำหนดค่าไว้ล่วงหน้า ซึ่งเชื่อมโยงรูปแบบทั่วไป เช่น แบบทึบ แบบโทนสี หรือแบบร่าง กับบทบาทที่เหมาะสมจาก ColorScheme ที่ใช้งานอยู่ภายใน MaterialScope ซึ่งจะช่วยให้คุณใช้รูปแบบที่สอดคล้องกันได้โดยไม่ต้องกำหนดสีแต่ละสีด้วยตนเอง สำหรับปุ่มประเภททั่วไป

    textEdgeButton(
        colors = filledButtonColors(), // default
        /* OR colors = filledTonalButtonColors() */
        /* OR colors = filledVariantButtonColors() */
        // ... other parameters
    )

    สำหรับไพ่ ให้ใช้ฟังก์ชันในตระกูล filledCardColors() ที่เทียบเท่า

    นอกจากนี้ คุณยังแก้ไขButtonColorsออบเจ็กต์ที่ฟังก์ชันตัวช่วยส่งคืน ได้โดยใช้เมธอด copy() หากต้องการเปลี่ยนโทเค็นเพียง 1 หรือ 2 รายการ

    textEdgeButton(
        colors =
        filledButtonColors()
            .copy(
                containerColor = colorScheme.tertiary,
                labelColor = colorScheme.onTertiary
            ),
        // ... other parameters
    )

  2. ระบุบทบาทสีแทนอย่างชัดเจน สร้างออบเจ็กต์ ButtonColors ของคุณเอง แล้วส่งไปยังคอมโพเนนต์ สำหรับบัตร ให้ใช้วัตถุ CardColors ที่เทียบเท่า

    textEdgeButton(
        colors =
        ButtonColors(
            // the materialScope makes colorScheme available
            containerColor = colorScheme.secondary,
            iconColor = colorScheme.secondaryDim,
            labelColor = colorScheme.onSecondary,
            secondaryLabelColor = colorScheme.onSecondary
        ),
        // ... other parameters
    )

  3. ระบุสีคงที่ (ใช้อย่างระมัดระวัง) แม้ว่าโดยทั่วไปเราจะแนะนำให้ระบุสีตามบทบาทเชิงความหมาย (เช่น colorScheme.primary) แต่คุณก็ระบุค่าสีโดยตรงได้เช่นกัน ควรใช้วิธีนี้อย่างระมัดระวัง เนื่องจากอาจทำให้ธีมโดยรวมไม่สอดคล้องกัน โดยเฉพาะอย่างยิ่งหากธีมมีการเปลี่ยนแปลงแบบไดนามิก

    textEdgeButton(
        colors = filledButtonColors().copy(
            containerColor = android.graphics.Color.RED.argb, // Using named colors
            labelColor = 0xFFFFFF00.toInt().argb // Using a hex code for yellow
        ),
        // ... other parameters
    )

การพิมพ์

ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้การพิมพ์อย่างมีประสิทธิภาพในการออกแบบได้ที่ คู่มือการออกแบบการพิมพ์

ข้อความทั้งหมดในการ์ดจะแสดงผลโดยใช้แบบอักษรที่ระบบจัดเตรียมไว้ให้ เพื่อสร้างความสอดคล้องด้านภาพในแพลตฟอร์ม Wear OS และเพิ่มประสิทธิภาพ กล่าวคือ ไทล์ไม่รองรับแบบอักษรที่กำหนดเอง ใน Wear OS 6 ขึ้นไป แบบอักษรนี้จะเป็นแบบอักษรเฉพาะ OEM ในกรณีส่วนใหญ่จะเป็นแบบอักษรแบบแปรผัน ซึ่งจะมอบประสบการณ์ที่สื่ออารมณ์ได้มากขึ้นและควบคุมได้ละเอียดยิ่งขึ้น

โดยปกติแล้ว หากต้องการสร้างรูปแบบข้อความ คุณจะใช้วิธี text() ร่วมกับค่าคงที่ทางอักขระศาสตร์ คอมโพเนนต์นี้ช่วยให้คุณใช้ประโยชน์จาก บทบาทการออกแบบตัวอักษรที่กำหนดไว้ล่วงหน้าใน Material 3 Expressive ซึ่งจะช่วยให้ไทล์ เป็นไปตามแนวทางปฏิบัติแนะนำด้านการออกแบบตัวอักษรที่กำหนดไว้เพื่อให้อ่านง่ายและมีลำดับชั้น ไลบรารีมีค่าคงที่ของแบบตัวพิมพ์เชิงความหมาย 18 รายการ เช่น BODY_MEDIUM ค่าคงที่เหล่านี้ยังส่งผลต่อแกนแบบอักษรอื่นๆ นอกเหนือจากขนาดด้วย

text(
    text = "Hello, World!".layoutString,
    typography = BODY_MEDIUM,
)

หากต้องการควบคุมเพิ่มเติม คุณสามารถระบุการตั้งค่าเพิ่มเติมได้ ใน Wear OS 6 ขึ้นไป ระบบน่าจะใช้แบบอักษรแบบแปรผัน ซึ่งคุณสามารถแก้ไขตามแกนตัวเอียง น้ำหนัก ความกว้าง และความกลม คุณควบคุมแกนเหล่านี้ได้ โดยใช้พารามิเตอร์ settings

text(
    text = "Hello, World".layoutString,
    italic = true,

    // Use elements defined in androidx.wear.protolayout.LayoutElementBuilders.FontSetting
    settings =
    listOf(
        weight(500),
        width(100F),
        roundness(100)
    ),
)

สุดท้ายนี้ หากต้องการควบคุมขนาดหรือระยะห่างระหว่างตัวอักษร (ไม่แนะนำ) ให้ใช้ basicText() แทน text() และสร้างค่าสำหรับพร็อพเพอร์ตี้ fontStyle โดยใช้ fontStyle()

รูปร่างและขอบ

คุณเปลี่ยนรัศมีมุมของคอมโพเนนต์เกือบทุกรายการได้โดยใช้พร็อพเพอร์ตี้shape ของคอมโพเนนต์นั้น ค่ามาจากพร็อพเพอร์ตี้ MaterialScope shapes ดังนี้

textButton(
    height = expand(),
    width = expand(),
    shape = shapes.medium, // OR another value like shapes.full
    colors = filledVariantButtonColors(),
    labelContent = { text("Hello, World!".layoutString) },
)

หลังจากเปลี่ยนรูปร่างของคอมโพเนนต์แล้ว หากคิดว่ามีพื้นที่มากเกินไปหรือน้อยเกินไปรอบขอบของจอแสดงผล ให้ปรับขอบโดยใช้พารามิเตอร์ margin ของ primaryLayout() ดังนี้

primaryLayout(
    mainSlot = {
        textButton(
            shape = shapes.small,
            /* ... */
        )
    },
    // margin constants defined in androidx.wear.protolayout.material3.PrimaryLayoutMargins
    margins = MAX_PRIMARY_LAYOUT_MARGIN,
)

เส้นโค้ง

ระบบรองรับองค์ประกอบย่อยของคอนเทนเนอร์ Arc ต่อไปนี้

  • ArcLine: แสดงเส้นโค้งรอบอาร์ค
  • ArcText: แสดงข้อความโค้งใน Arc
  • ArcAdapter: แสดงผลองค์ประกอบเลย์เอาต์พื้นฐานในส่วนโค้ง โดยวาดที่เส้นสัมผัสของส่วนโค้ง

ดูข้อมูลเพิ่มเติมได้ที่เอกสารอ้างอิงสำหรับองค์ประกอบแต่ละประเภท

คีย์ตัวปรับแต่ง

องค์ประกอบเลย์เอาต์ที่มีอยู่ทุกรายการสามารถมีตัวแก้ไขที่ใช้กับองค์ประกอบนั้นได้โดยไม่บังคับ ใช้ตัวแก้ไขเหล่านี้เพื่อวัตถุประสงค์ต่อไปนี้

  • เปลี่ยนลักษณะที่ปรากฏของเลย์เอาต์ เช่น เพิ่มพื้นหลัง เส้นขอบ หรือระยะห่างจากขอบให้กับองค์ประกอบเลย์เอาต์
  • เพิ่มข้อมูลเมตาเกี่ยวกับเลย์เอาต์ เช่น เพิ่มตัวแก้ไขความหมายลงในองค์ประกอบ เลย์เอาต์เพื่อใช้กับโปรแกรมอ่านหน้าจอ
  • เพิ่มฟังก์ชันการทำงาน เช่น เพิ่มตัวแก้ไขที่คลิกได้ลงในเลย์เอาต์ องค์ประกอบเพื่อให้ไทล์โต้ตอบได้ ดูข้อมูลเพิ่มเติมได้ที่โต้ตอบกับไทล์

ตัวอย่างเช่น เราสามารถปรับแต่งรูปลักษณ์และข้อมูลเมตาเริ่มต้นของ Image ดังที่แสดงในตัวอย่างโค้ดต่อไปนี้

private fun myImage(): LayoutElement =
    Image.Builder()
        .setWidth(dp(24f))
        .setHeight(dp(24f))
        .setResourceId("image_id")
        .setModifiers(
            Modifiers.Builder()
                .setBackground(Background.Builder().setColor(argb(0xFFFF0000.toInt())).build())
                .setPadding(ModifiersBuilders.Padding.Builder().setStart(dp(12f)).build())
                .setSemantics(Semantics.Builder().setContentDescription("Image description").build())
                .build()
        )
        .build()

Spannables

Spannable เป็นคอนเทนเนอร์ประเภทพิเศษที่จัดวางองค์ประกอบคล้ายกับข้อความ ซึ่งจะมีประโยชน์เมื่อคุณต้องการใช้สไตล์อื่นกับสตริงย่อยเพียงสตริงเดียวในบล็อกข้อความขนาดใหญ่ ซึ่งเป็นสิ่งที่ทำไม่ได้ด้วยองค์ประกอบ Text

คอนเทนเนอร์ Spannable เต็มไปด้วยองค์ประกอบย่อย Span ไม่อนุญาตให้ใช้เด็กคนอื่นๆ หรืออินสแตนซ์ Spannable ที่ซ้อนกัน

Spanเด็กมี 2 ประเภท ได้แก่

  • SpanText: แสดงข้อความด้วยรูปแบบที่เฉพาะเจาะจง
  • SpanImage: แสดงรูปภาพในบรรทัดเดียวกับข้อความ

เช่น คุณอาจทำให้คำว่า "world" ในไทล์ "Hello world" เป็นตัวเอียงและแทรก รูปภาพระหว่างคำ ดังที่แสดงในตัวอย่างโค้ดต่อไปนี้

private fun mySpannable(): LayoutElement =
    LayoutElementBuilders.Spannable.Builder()
        .addSpan(SpanText.Builder().setText("Hello ").build())
        .addSpan(SpanImage.Builder().setWidth(dp(24f)).setHeight(dp(24f)).setResourceId("image_id").build())
        .addSpan(
            SpanText.Builder()
                .setText("world")
                .setFontStyle(FontStyle.Builder().setItalic(true).build())
                .build()
        )
        .build()

ใช้งานกับทรัพยากร

ไทล์ไม่มีสิทธิ์เข้าถึงทรัพยากรใดๆ ของแอป ซึ่งหมายความว่าคุณไม่สามารถส่งรหัสรูปภาพ Android ไปยังองค์ประกอบเลย์เอาต์ Image และคาดหวังให้ระบบ แก้ไขได้ แต่ให้ลบล้างเมธอด onTileResourcesRequest() และ ระบุทรัพยากรด้วยตนเอง

คุณระบุรูปภาพภายในเมธอด onTileResourcesRequest() ได้ 2 วิธี ดังนี้

  • ระบุทรัพยากรที่วาดได้โดยใช้ setAndroidResourceByResId()
  • ระบุรูปภาพแบบไดนามิกเป็น ByteArray โดยใช้ setInlineResource()

override fun onTileResourcesRequest(
    requestParams: ResourcesRequest
) = Futures.immediateFuture(
    Resources.Builder()
        .setVersion("1")
        .addIdToImageMapping(
            "image_from_resource",
            ResourceBuilders.ImageResource.Builder()
                .setAndroidResourceByResId(
                    ResourceBuilders.AndroidImageResourceByResId.Builder()
                        .setResourceId(R.drawable.ic_walk)
                        .build()
                ).build()
        )
        .addIdToImageMapping(
            "image_inline",
            ResourceBuilders.ImageResource.Builder()
                .setInlineResource(
                    ResourceBuilders.InlineImageResource.Builder()
                        .setData(imageAsByteArray)
                        .setWidthPx(48)
                        .setHeightPx(48)
                        .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565)
                        .build()
                ).build()
        ).build()
)

รายการตรวจสอบรูปภาพตัวอย่างการ์ด

ระบบจะแสดงรูปภาพตัวอย่างการ์ดที่อ้างอิงในไฟล์ Manifest ของแอป Android ในเครื่องมือแก้ไขภาพสไลด์ของการ์ดเพื่อเพิ่มการ์ดใหม่ โดยเอดิเตอร์นี้จะปรากฏ ทั้งในอุปกรณ์ Wear OS และในแอปที่ใช้ร่วมกันของนาฬิกาในโทรศัพท์

โปรดตรวจสอบรายละเอียดต่อไปนี้เกี่ยวกับไทล์เพื่อช่วยให้ผู้ใช้ได้รับประโยชน์สูงสุดจากรูปภาพตัวอย่างนี้

  • แสดงการออกแบบล่าสุด ตัวอย่างควรแสดงการออกแบบล่าสุดของ ไทล์อย่างถูกต้อง
  • ใช้ขนาดที่แนะนำ รูปภาพตัวอย่างควรมีขนาด 400x400 พิกเซลเพื่อให้แสดงผลได้ดีที่สุด และมอบประสบการณ์การใช้งานที่ดีแก่ผู้ใช้
  • ใช้ธีมสีแบบคงที่ ใช้ธีมสีแบบคงที่ของไทล์ ไม่ใช่ธีมสีแบบไดนามิก
  • มีไอคอนแอป ยืนยันว่าไอคอนของแอปปรากฏที่ด้านบนของ รูปภาพตัวอย่าง
  • แสดงสถานะที่โหลด/เข้าสู่ระบบ ตัวอย่างควรแสดงสถานะ "โหลดแล้ว" หรือ "เข้าสู่ระบบแล้ว" ที่ทำงานได้อย่างเต็มที่ โดยหลีกเลี่ยงเนื้อหาที่ว่างเปล่าหรือเนื้อหาตัวยึดตำแหน่ง
  • ใช้ประโยชน์จากกฎการแก้ปัญหาทรัพยากรเพื่อการปรับแต่ง (ไม่บังคับ) ลองใช้กฎความละเอียดของทรัพยากรของ Android เพื่อแสดงตัวอย่าง ที่ตรงกับการตั้งค่าขนาดการแสดงผล ภาษา หรือภาษาและภูมิภาคของอุปกรณ์ ซึ่งจะมีประโยชน์อย่างยิ่งหากลักษณะของไทล์แตกต่างกันในอุปกรณ์ต่างๆ