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


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

Groovy

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

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

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

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

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

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

Kotlin

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

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

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

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

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

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

หัวข้อสำคัญ

ไทล์ไม่ได้สร้างขึ้นในลักษณะเดียวกับแอป 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>

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

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

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

ไทล์ &quot;Hello World&quot;
รูปที่ 1 ไทล์ "Hello World"

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

สร้าง 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(text = "Action".layoutString) }
        )
    }
    

สล็อต

ใน 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(): ปุ่มขอบที่มีช่องเดียวสำหรับถ่ายภาพข้อความหรือเนื้อหาที่ยาวและกว้างคล้ายกัน

บัตรต่างๆ

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

สัญญาณบอกสถานะความคืบหน้า

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

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

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

ธีม

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

ระบบสีที่สื่อความหมายของ Material 3
รูปที่ 3 ระบบสีที่สื่ออารมณ์ของ Material 3

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

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

val myColorScheme =
    ColorScheme(
        primary = ...
        onPrimary = ...
        // 27 more
    )

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

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

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

สี

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

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

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

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

  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.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: แสดงผลข้อความโค้งในอาร์ค
  • ArcAdapter: แสดงผลองค์ประกอบเลย์เอาต์พื้นฐานในส่วนโค้ง ซึ่งวาดในแนวสัมผัสกับส่วนโค้ง

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

ตัวปรับแต่ง

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

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

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

Kotlin

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

Java

private LayoutElement myImage() {
   return new Image.Builder()
           .setWidth(dp(24f))
           .setHeight(dp(24f))
           .setResourceId("image_id")
           .setModifiers(new Modifiers.Builder()
                   .setBackground(new Background.Builder().setColor(argb(0xFFFF0000)).build())
                   .setPadding(new Padding.Builder().setStart(dp(12f)).build())
                   .setSemantics(new Semantics.Builder()
                           .setContentDescription("Image description")
                           .build()
                   ).build()
           ).build();
}

เนื้อหาที่ขยายได้

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

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

Span ย่อยมี 2 ประเภทดังนี้

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

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

Kotlin

private fun mySpannable(): LayoutElement =
    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()

Java

private LayoutElement mySpannable() {
   return new Spannable.Builder()
        .addSpan(new SpanText.Builder()
            .setText("Hello ")
            .build()
        )
        .addSpan(new SpanImage.Builder()
            .setWidth(dp(24f))
            .setHeight(dp(24f))
            .setResourceId("image_id")
            .build()
        )
        .addSpan(new SpanText.Builder()
            .setText("world")
            .setFontStyle(newFontStyle.Builder()
                .setItalic(true)
                .build())
            .build()
        ).build();
}

ทำงานกับทรัพยากร

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

การให้รูปภาพภายในเมธอด onTileResourcesRequest() ทำได้ 2 วิธีดังนี้

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

Kotlin

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

Java

@Override
protected ListenableFuture<Resources> onTileResourcesRequest(
       @NonNull ResourcesRequest requestParams
) {
return Futures.immediateFuture(
    new Resources.Builder()
        .setVersion("1")
        .addIdToImageMapping("image_from_resource", new ImageResource.Builder()
            .setAndroidResourceByResId(new AndroidImageResourceByResId.Builder()
                .setResourceId(R.drawable.image_id)
                .build()
            ).build()
        )
        .addIdToImageMapping("image_inline", new ImageResource.Builder()
            .setInlineResource(new InlineImageResource.Builder()
                .setData(imageAsByteArray)
                .setWidthPx(48)
                .setHeightPx(48)
                .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565)
                .build()
            ).build()
        ).build()
);
}

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

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

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

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