หากต้องการเริ่มแสดงไทล์จากแอป ให้รวมทรัพยากร Dependency ต่อไปนี้ไว้ในไฟล์ build.gradle ของแอป
Groovy
dependencies { // Use to implement support for wear tiles implementation "androidx.wear.tiles:tiles:1.6.2" // Use to utilize standard components and layouts in your tiles implementation "androidx.wear.protolayout:protolayout:1.4.2" // Use to utilize components and layouts with Material Design in your tiles implementation "androidx.wear.protolayout:protolayout-material:1.4.2" // Use to include dynamic expressions in your tiles implementation "androidx.wear.protolayout:protolayout-expression:1.4.2" // Use to preview wear tiles in your own app debugImplementation "androidx.wear.tiles:tiles-renderer:1.6.2" // Use to fetch tiles from a tile provider in your tests testImplementation "androidx.wear.tiles:tiles-testing:1.6.2" }
Kotlin
dependencies { // Use to implement support for wear tiles implementation("androidx.wear.tiles:tiles:1.6.2") // Use to utilize standard components and layouts in your tiles implementation("androidx.wear.protolayout:protolayout:1.4.2") // Use to utilize components and layouts with Material Design in your tiles implementation("androidx.wear.protolayout:protolayout-material:1.4.2") // Use to include dynamic expressions in your tiles implementation("androidx.wear.protolayout:protolayout-expression:1.4.2") // Use to preview wear tiles in your own app debugImplementation("androidx.wear.tiles:tiles-renderer:1.6.2") // Use to fetch tiles from a tile provider in your tests testImplementation("androidx.wear.tiles:tiles-testing:1.6.2") }
หัวข้อสำคัญ
ไทล์ไม่ได้สร้างขึ้นในลักษณะเดียวกับแอป Android และใช้แนวคิดที่แตกต่างกัน ดังนี้
- เทมเพลตเลย์เอาต์: กำหนดการจัดเรียงโดยรวมขององค์ประกอบภาพบน
จอแสดงผล โดยใช้ฟังก์ชัน
primaryLayout() - องค์ประกอบเลย์เอาต์: แสดงองค์ประกอบกราฟิกแต่ละรายการ เช่น ปุ่มหรือการ์ด หรือองค์ประกอบดังกล่าวหลายรายการที่จัดกลุ่มเข้าด้วยกันโดยใช้คอลัมน์ buttonGroup หรือองค์ประกอบที่คล้ายกัน ซึ่งจะฝังอยู่ในเทมเพลตเลย์เอาต์
- ทรัพยากร: ออบเจ็กต์
ResourceBuilders.Resourcesประกอบด้วยแผนที่ ของคู่คีย์-ค่าของทรัพยากร Android (รูปภาพ) ที่จำเป็นต่อการ แสดงผลเลย์เอาต์ และเวอร์ชัน - ไทม์ไลน์: ออบเจ็กต์
TimelineBuilders.Timelineคือรายการของอินสแตนซ์อย่างน้อย 1 รายการของออบเจ็กต์เลย์เอาต์ คุณสามารถระบุกลไกและ นิพจน์ต่างๆ เพื่อระบุเวลาที่โปรแกรมแสดงผลควรเปลี่ยนจากออบเจ็กต์เลย์เอาต์หนึ่ง ไปยังอีกออบเจ็กต์หนึ่ง เช่น เพื่อหยุดแสดงเลย์เอาต์ในเวลาที่เฉพาะเจาะจง - สถานะ: โครงสร้างข้อมูลประเภท
StateBuilders.Stateที่ส่งผ่านระหว่างไทล์กับแอป เพื่อให้คอมโพเนนต์ทั้ง 2 สื่อสารกันได้ เช่น หากมีการแตะปุ่มในไทล์ สถานะ จะมีรหัสของปุ่ม นอกจากนี้ คุณยังแลกเปลี่ยนประเภทข้อมูลโดยใช้แผนที่ได้ด้วย - ไทล์: ออบเจ็กต์
TileBuilders.Tileที่แสดงถึงไทล์ ซึ่งประกอบด้วยไทม์ไลน์ รหัสเวอร์ชันของทรัพยากร ช่วงความสดใหม่ และสถานะ - Protolayout: คำนี้ปรากฏในชื่อของคลาสต่างๆ ที่เกี่ยวข้องกับไทล์ และหมายถึงไลบรารี Protolayout ของ Wear OS ซึ่งเป็นไลบรารีกราฟิก ที่ใช้ในแพลตฟอร์มต่างๆ ของ Wear OS
สร้างไทล์
ใช้ Material3TileService (แนะนำ)
เมื่อสร้างไทล์ Material 3 (androidx.wear.tiles:tiles:1.6.0 ขึ้นไป)
ให้ขยาย Material3TileService เสมอแทนที่จะใช้คลาส TileService ระดับล่าง Material3TileService มีสถาปัตยกรรมที่เน้น Kotlin เป็นหลัก
ซึ่งช่วยลดความซับซ้อนในการพัฒนาไทล์
- โครูทีน Kotlin ในตัว: ใช้ฟังก์ชัน
MaterialScope.tileResponse(requestParams: TileRequest): Tileเดียวที่ระงับ แทนการใช้ListenableFutureและการลบล้างonTileRequest() - กำหนดค่าไว้ล่วงหน้า
MaterialScope:tileResponse()ทำงานโดยมีMaterialScopeเป็นตัวรับ (กำหนดค่าผ่านพารามิเตอร์ของตัวสร้าง เช่นallowDynamicThemeและdefaultColorScheme) คุณจึงไม่จำเป็นต้อง ห่อเลย์เอาต์ในการเรียกmaterialScope()ที่ซ้ำซ้อน - การลงทะเบียนทรัพยากรในการเรียกใช้ครั้งเดียว: รวมถึง
ProtoLayoutScopeเพื่อ ลงทะเบียนทรัพยากรรูปภาพในบรรทัดโดยอัตโนมัติ และแสดงทั้งเลย์เอาต์ไทล์ และทรัพยากรในการเรียกใช้ Binder ของระบบครั้งเดียว เนื่องจากMaterial3TileServiceจัดการทรัพยากรโดยอัตโนมัติ (finalonTileResourcesRequest()) จึงไม่ต้องลบล้างonTileResourcesRequest()
class MyTileService : Material3TileService() { override suspend fun MaterialScope.tileResponse(requestParams: TileRequest): Tile = tile( timeline = Timeline.fromLayoutElement( primaryLayout( mainSlot = { text("Hello, World!".layoutString, typography = BODY_LARGE) } ) ) ) }
TileService สถาปัตยกรรมพื้นฐาน
Material3TileService สร้างขึ้นบนคลาสพื้นฐาน TileService
ซึ่งตัวอย่างที่เหลือในคู่มือนี้ใช้เพื่ออธิบายแนวคิดระดับต่ำ
หากต้องการระบุไทล์จากแอป ให้ใช้บริการประเภท 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 จึงสามารถ ปรับเปลี่ยนตัวอย่างตามปัจจัยต่างๆ เช่น ขนาดหน้าจอและภาษาของอุปกรณ์ได้ ดูคำแนะนำเพิ่มเติมได้ในรายการตรวจสอบการแสดงตัวอย่าง
ติดตั้งใช้งานแอปและเพิ่มไทล์ลงในภาพหมุนของไทล์ (นอกจากนี้ยังมีวิธีแสดงตัวอย่างไทล์ที่เป็นมิตรกับนักพัฒนาแอปมากขึ้นด้วย แต่ตอนนี้ให้ทำด้วยตนเองก่อน)
ดูตัวอย่างที่สมบูรณ์ได้ในตัวอย่างโค้ดใน GitHub หรือโค้ดแล็บ
สร้าง UI สำหรับการ์ด
องค์ประกอบ UI ที่สื่ออารมณ์ของ Material 3 สร้างขึ้นโดยใช้แนวทางที่มีโครงสร้าง ซึ่งขับเคลื่อนโดยรูปแบบตัวสร้างที่ปลอดภัยด้านประเภทของ Kotlin
การจัดวาง
ดูคำแนะนำเกี่ยวกับหลักการออกแบบเบื้องหลังการสร้างเลย์เอาต์การ์ดที่มีประสิทธิภาพและปรับเปลี่ยนตามพื้นที่โฆษณาได้ในเลย์เอาต์ทั่วไปสำหรับการ์ด
หากต้องการสร้างเลย์เอาต์ ให้ทำดังนี้
เริ่มต้นขอบเขต Material Design: เรียกใช้ฟังก์ชัน
materialScope()โดยระบุcontextและdeviceConfigurationที่จำเป็น คุณ สามารถใส่พารามิเตอร์ที่ไม่บังคับ เช่นallowDynamicThemeและdefaultColorSchemeallowDynamicThemeจะเป็นtrueโดยค่าเริ่มต้น และdefaultColorSchemeจะแสดงถึงColorSchemeที่ใช้เมื่อไม่มีสีแบบไดนามิก เช่น เมื่อผู้ใช้ปิดฟีเจอร์นี้ หรือ เมื่ออุปกรณ์ไม่รองรับ หรือallowDynamicThemeเป็นfalse)สร้าง 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 ช่อง โดยจากบนลงล่างจะมีดังนี้
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 กลุ่ม ได้แก่ สีหลัก สีรอง สีเสริม สีข้อผิดพลาด สีพื้นผิว และสีเส้นขอบ
ColorScheme จะแมปบทบาททั้ง 29 บทบาทนี้กับสีที่เกี่ยวข้อง และ
เนื่องจากเป็นส่วนหนึ่งของ 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" แทน "หลัก" เพื่อให้
โดดเด่นและมีคอนทราสต์ที่ดีขึ้น
คุณปรับแต่งสีของคอมโพเนนต์ได้หลายวิธี ดังนี้
ใช้ฟังก์ชันตัวช่วยสำหรับสีที่กำหนดไว้ล่วงหน้า ใช้ฟังก์ชันช่วย เช่น
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 )
ระบุบทบาทสีแทนที่อย่างชัดเจน สร้างออบเจ็กต์
ButtonColorsของคุณเอง แล้วส่งไปยังคอมโพเนนต์ สำหรับบัตร ให้ใช้ออบเจ็กต์CardColorsที่เทียบเท่าtextEdgeButton( colors = ButtonColors( // the materialScope makes colorScheme available containerColor = colorScheme.secondary, iconColor = colorScheme.secondaryDim, labelColor = colorScheme.onSecondary, secondaryLabelColor = colorScheme.onSecondary ), // ... other parameters )
ระบุสีคงที่ (ใช้อย่างระมัดระวัง) แม้ว่าโดยทั่วไปเราจะแนะนำให้ระบุสีตามบทบาทเชิงความหมาย (เช่น
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: แสดงข้อความโค้งใน ArcArcAdapter: แสดงผลองค์ประกอบเลย์เอาต์พื้นฐานในส่วนโค้ง โดยวาดที่เส้นสัมผัสของส่วนโค้ง
ดูข้อมูลเพิ่มเติมได้ที่เอกสารอ้างอิงสำหรับองค์ประกอบแต่ละประเภท
คีย์ตัวปรับแต่ง
องค์ประกอบเลย์เอาต์ที่มีอยู่ทุกรายการสามารถเลือกใช้ตัวแก้ไขได้ ใช้ ตัวแก้ไขเหล่านี้เพื่อวัตถุประสงค์ต่อไปนี้
- เปลี่ยนลักษณะที่ปรากฏของเลย์เอาต์ เช่น เพิ่มพื้นหลัง เส้นขอบ หรือระยะห่างจากขอบให้กับองค์ประกอบเลย์เอาต์
- เพิ่มข้อมูลเมตาเกี่ยวกับเลย์เอาต์ เช่น เพิ่มตัวแก้ไขความหมายลงในองค์ประกอบ เลย์เอาต์เพื่อใช้กับโปรแกรมอ่านหน้าจอ
- เพิ่มฟังก์ชันการทำงาน เช่น เพิ่มตัวแก้ไขที่คลิกได้ลงในเลย์เอาต์ องค์ประกอบเพื่อให้ไทล์โต้ตอบได้ ดูข้อมูลเพิ่มเติมได้ที่ โต้ตอบกับไทล์
ตัวอย่างเช่น เราสามารถปรับแต่งรูปลักษณ์และข้อมูลเมตาเริ่มต้นของ 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 ประเภท ได้แก่
เช่น คุณอาจทำให้คำว่า "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 เพื่อแสดงตัวอย่าง ที่ตรงกับการตั้งค่าขนาดการแสดงผล ภาษา หรือภาษาของอุปกรณ์ ซึ่งจะเป็นประโยชน์อย่างยิ่งหากลักษณะที่ปรากฏของไทล์แตกต่างกันไปในแต่ละอุปกรณ์