หากต้องการเริ่มใส่การ์ดจากแอป ให้ใส่ทรัพยากร Dependency ต่อไปนี้ใน
build.gradle
ของแอป
Groovy
dependencies { // Use to implement support for wear tiles implementation "androidx.wear.tiles:tiles:1.5.0-alpha03" // Use to utilize standard components and layouts in your tiles implementation "androidx.wear.protolayout:protolayout:1.3.0-alpha03" // Use to utilize components and layouts with Material Design in your tiles implementation "androidx.wear.protolayout:protolayout-material:1.3.0-alpha03" // Use to include dynamic expressions in your tiles implementation "androidx.wear.protolayout:protolayout-expression:1.3.0-alpha03" // Use to preview wear tiles in your own app debugImplementation "androidx.wear.tiles:tiles-renderer:1.5.0-alpha03" // Use to fetch tiles from a tile provider in your tests testImplementation "androidx.wear.tiles:tiles-testing:1.5.0-alpha03" }
Kotlin
dependencies { // Use to implement support for wear tiles implementation("androidx.wear.tiles:tiles:1.5.0-alpha03") // Use to utilize standard components and layouts in your tiles implementation("androidx.wear.protolayout:protolayout:1.3.0-alpha03") // Use to utilize components and layouts with Material Design in your tiles implementation("androidx.wear.protolayout:protolayout-material:1.3.0-alpha03") // Use to include dynamic expressions in your tiles implementation("androidx.wear.protolayout:protolayout-expression:1.3.0-alpha03") // Use to preview wear tiles in your own app debugImplementation("androidx.wear.tiles:tiles-renderer:1.5.0-alpha03") // Use to fetch tiles from a tile provider in your tests testImplementation("androidx.wear.tiles:tiles-testing:1.5.0-alpha03") }
สร้างไทล์
หากต้องการจัดเตรียมการ์ดจากแอปพลิเคชันของคุณ ให้สร้างชั้นเรียนที่ขยาย
TileService
และติดตั้งใช้งานเมธอดดังที่แสดงในตัวอย่างโค้ดต่อไปนี้
Kotlin
// Uses the ProtoLayout namespace for tile timeline objects. // If you haven't done so already, migrate to the ProtoLayout namespace. import androidx.wear.protolayout.TimelineBuilders.Timeline import androidx.wear.protolayout.material.Text import androidx.wear.tiles.TileBuilders.Tile private val RESOURCES_VERSION = "1" class MyTileService : TileService() { override fun onTileRequest(requestParams: RequestBuilders.TileRequest) = Futures.immediateFuture(Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline( Timeline.fromLayoutElement( Text.Builder(this, "Hello world!") .setTypography(Typography.TYPOGRAPHY_DISPLAY1) .setColor(argb(0xFF000000.toInt())) .build())) .build()) override fun onTileResourcesRequest(requestParams: ResourcesRequest) = Futures.immediateFuture(Resources.Builder() .setVersion(RESOURCES_VERSION) .build() ) }
Java
// Uses the ProtoLayout namespace for tile timeline objects. // If you haven't done so already, migrate to the ProtoLayout namespace. import androidx.wear.protolayout.TimelineBuilders.Timeline; import androidx.wear.protolayout.material.Text; import androidx.wear.tiles.TileBuilders.Tile; public class MyTileService extends TileService { private static final String RESOURCES_VERSION = "1"; @NonNull @Override protected ListenableFuture<Tile> onTileRequest( @NonNull TileRequest requestParams ) { return Futures.immediateFuture(new Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline( Timeline.fromLayoutElement( new Text.Builder(this, "Hello world!") .setTypography(Typography.TYPOGRAPHY_DISPLAY1) .setColor(ColorBuilders.argb(0xFF000000)) .build())) .build() ); } @NonNull @Override protected ListenableFuture<Resources> onTileResourcesRequest( @NonNull ResourcesRequest requestParams ) { return Futures.immediateFuture(new Resources.Builder() .setVersion(RESOURCES_VERSION) .build() ); } }
ถัดไป ให้เพิ่มบริการภายในแท็ก <application>
ของ
AndroidManifest.xml
<service android:name=".MyTileService" android:label="@string/tile_label" android:description="@string/tile_description" android:icon="@drawable/tile_icon_round" android:roundIcon="@drawable/tile_icon_round" 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 จะลงทะเบียนบริการนี้เป็นผู้ให้บริการการ์ด
ไอคอน ป้ายกำกับ และคำอธิบายจะแสดงต่อผู้ใช้เมื่อกำหนดค่าชิ้นส่วน บนโทรศัพท์หรือนาฬิกา
ใช้แท็กข้อมูลเมตาตัวอย่างเพื่อแสดงตัวอย่างการ์ดเมื่อกําหนดค่าการ์ด ในโทรศัพท์
ภาพรวมวงจรชีวิตของบริการการ์ด
เมื่อคุณสร้างและประกาศ TileService
ในไฟล์ Manifest ของแอปแล้ว คุณจะ
สามารถตอบสนองต่อการเปลี่ยนแปลงสถานะของบริการการ์ด
TileService
เป็นบริการที่มีผลผูกพัน ผลลัพธ์จะผูกกับ TileService
คำขอของแอป หรือว่าระบบจำเป็นต้องสื่อสารกับแอปหรือไม่ ทั่วไป
อายุการใช้งานของ bound-service มีวิธี Callback 4 วิธีดังนี้
onCreate()
, onBind()
, onUnbind()
และ
onDestroy()
ระบบจะเรียกใช้เมธอดเหล่านี้ทุกครั้งที่บริการ
เข้าสู่ช่วงใหม่ของวงจร
นอกจาก Callback ที่ควบคุมวงจรของบริการที่ผูกไว้แล้ว คุณยังทําสิ่งต่อไปนี้ได้
ใช้วิธีการอื่นๆ ที่เฉพาะเจาะจงกับวงจรของ TileService
ไทล์ทั้งหมด
บริการต้องติดตั้งใช้งาน onTileRequest()
และ onTileResourcesRequest()
เพื่อ
ตอบสนองต่อคำขออัปเดตจากระบบ
onTileAddEvent()
: ระบบจะเรียกใช้เมธอดนี้เฉพาะเมื่อผู้ใช้ เพิ่มการ์ดของคุณเป็นครั้งแรก และหากผู้ใช้นำการ์ดออกและเพิ่ม อีกครั้ง นี่คือช่วงเวลาที่ดีที่สุดในการเริ่มต้นแบบครั้งเดียวระบบจะเรียก
onTileAddEvent()
เมื่อมีการกำหนดค่าใหม่ชุดการ์ดเท่านั้น ไม่เมื่อใดก็ตามที่ระบบสร้างการ์ด เช่น เมื่ออุปกรณ์ รีบูตหรือเปิดเครื่องแล้ว จะไม่มีการเรียกonTileAddEvent()
สำหรับการ์ด ที่มีการเพิ่มลงไปแล้ว คุณใช้getActiveTilesAsync()
ได้ แทนที่จะได้รับสแนปชอตว่าการ์ดใดที่เป็นของคุณทำงานอยู่onTileRemoveEvent()
: ระบบจะเรียกใช้เมธอดนี้ก็ต่อเมื่อผู้ใช้ นำการ์ดของคุณออกonTileEnterEvent()
: ระบบจะเรียกใช้เมธอดนี้เมื่อการ์ด จากผู้ให้บริการรายนี้จะแสดงให้เห็นบนหน้าจอonTileLeaveEvent()
: ระบบจะเรียกใช้เมธอดนี้เมื่อการ์ด ที่มาจากผู้ให้บริการรายนี้ไม่ปรากฏบนหน้าจอonTileRequest()
: ระบบจะเรียกใช้เมธอดนี้เมื่อระบบ ขอไทม์ไลน์ใหม่จากผู้ให้บริการรายนี้onTileResourcesRequest()
: ระบบจะเรียกใช้เมธอดนี้เมื่อการเรียก ระบบขอแพ็กเกจทรัพยากรจากผู้ให้บริการรายนี้ กรณีนี้เกิดขึ้นได้ ในครั้งแรกที่มีการโหลด Tile หรือเมื่อใดก็ตามที่เวอร์ชันทรัพยากร การเปลี่ยนแปลง
ค้นหาว่าไทล์ใดที่ใช้งานอยู่
การ์ดที่ใช้งานอยู่คือการ์ดที่ได้รับการเพิ่มไปยังนาฬิกา ใช้
เมธอดแบบคงที่ของ TileService
getActiveTilesAsync()
เพื่อค้นหาการ์ด
ของแอปของคุณทำงานอยู่
สร้าง UI สำหรับไทล์
เลย์เอาต์ของชิ้นส่วนจะเขียนโดยใช้รูปแบบของเครื่องมือสร้าง เลย์เอาต์ของการ์ดคือ สร้างขึ้นเหมือนต้นไม้ซึ่งประกอบด้วยคอนเทนเนอร์เลย์เอาต์และเลย์เอาต์พื้นฐาน จากองค์ประกอบเหล่านี้ องค์ประกอบการออกแบบแต่ละรายการจะมีคุณสมบัติ ที่คุณสามารถตั้งค่าผ่าน Setter Method
องค์ประกอบเลย์เอาต์พื้นฐาน
รองรับองค์ประกอบภาพต่อไปนี้จากไลบรารี protolayout
รวมถึงคอมโพเนนต์วัสดุ
Text
: แสดงผล สตริงข้อความ โดยไม่จำเป็นต้องมีการตัดข้อความImage
: จะแสดงรูปภาพSpacer
: มอบระยะห่างจากขอบระหว่างองค์ประกอบต่างๆ หรือทำหน้าที่เป็นเส้นแบ่งเมื่อคุณตั้ง สีพื้นหลัง
ส่วนประกอบของวัสดุ
นอกเหนือจากองค์ประกอบพื้นฐานแล้ว ไลบรารี protolayout-material
ยังมี
คอมโพเนนต์ที่ช่วยให้มีการออกแบบภาพสอดคล้องกับอินเทอร์เฟซผู้ใช้ของดีไซน์ Material
วิดีโอแนะนำ
Button
: คลิกได้ คอมโพเนนต์รูปวงกลมที่ออกแบบมาให้มีไอคอนChip
: คลิกได้ คอมโพเนนต์รูปทรงสนามกีฬาที่ออกแบบมาให้ประกอบด้วยข้อความสูงสุด 2 บรรทัด และ ไอคอนที่ไม่บังคับCompactChip
: คอมโพเนนต์รูปทรงสนามกีฬาที่คลิกได้ ซึ่งออกแบบมาให้มีบรรทัดข้อความTitleChip
: คอมโพเนนต์รูปทรงสนามกีฬาที่คลิกได้ซึ่งคล้ายกับChip
แต่มีขนาดใหญ่กว่า ความสูงเพื่อรองรับข้อความชื่อCircularProgressIndicator
: สัญญาณบอกสถานะความคืบหน้าแบบวงกลม ซึ่งสามารถวางไว้ในEdgeContentLayout
เพื่อแสดงความคืบหน้ารอบๆ ขอบของ บนหน้าจอ
คอนเทนเนอร์ของเลย์เอาต์
ระบบรองรับคอนเทนเนอร์ต่อไปนี้ พร้อมกับวัสดุ เลย์เอาต์
Row
: วาง องค์ประกอบย่อยในแนวนอน ทีละน้อยColumn
: วางองค์ประกอบย่อยในแนวตั้งทีละองค์ประกอบBox
: โฆษณาซ้อนทับ องค์ประกอบย่อยๆ ซ้อนทับกันArc
: วาง องค์ประกอบย่อยๆ กระจายออกไปในวงกลมSpannable
: ใช้แบบเฉพาะเจาะจงFontStyles
ไปยังส่วนของข้อความพร้อมกับข้อความและรูปภาพที่แทรกสลับกัน สำหรับข้อมูลเพิ่มเติม ดูข้อมูลที่หัวข้อโฆษณาแบบขยายได้
ทุกคอนเทนเนอร์อาจมีรายการย่อยได้อย่างน้อย 1 รายการ ซึ่งสามารถเป็น
คอนเทนเนอร์ ตัวอย่างเช่น Column
สามารถมีองค์ประกอบ Row
ได้หลายรายการ
เด็ก ทำให้ได้เค้าโครงที่เหมือนตาราง
ตัวอย่างเช่น การ์ดที่มีเลย์เอาต์คอนเทนเนอร์และองค์ประกอบเลย์เอาต์ย่อย 2 รายการ อาจมีลักษณะเช่นนี้
Kotlin
private fun myLayout(): LayoutElement = Row.Builder() .setWidth(wrap()) .setHeight(expand()) .setVerticalAlignment(VALIGN_BOTTOM) .addContent(Text.Builder() .setText("Hello world") .build() ) .addContent(Image.Builder() .setResourceId("image_id") .setWidth(dp(24f)) .setHeight(dp(24f)) .build() ).build()
Java
private LayoutElement myLayout() { return new Row.Builder() .setWidth(wrap()) .setHeight(expand()) .setVerticalAlignment(VALIGN_BOTTOM) .addContent(new Text.Builder() .setText("Hello world") .build() ) .addContent(new Image.Builder() .setResourceId("image_id") .setWidth(dp(24f)) .setHeight(dp(24f)) .build() ).build(); }
เลย์เอาต์ของวัสดุ
นอกจากเลย์เอาต์พื้นฐานแล้ว ไลบรารี protolayout-material
ยังมีฟีเจอร์บางส่วน
การจัดวางตามความคิดเห็นที่สร้างขึ้นเพื่อยึดองค์ประกอบใน "ช่อง" เฉพาะ
PrimaryLayout
: วางตำแหน่งการดำเนินการหลักรายการเดียวCompactChip
ที่ด้านล่างพร้อม เนื้อหาให้อยู่กึ่งกลางด้านบนMultiSlotLayout
: วางตำแหน่งป้ายกำกับหลักและป้ายกำกับรองที่มีเนื้อหาที่ไม่บังคับระหว่าง และCompactChip
(ไม่บังคับ) ที่ด้านล่างMultiButtonLayout
: กำหนดตำแหน่งชุดปุ่มที่จัดเรียงตามวัสดุ หลักเกณฑ์EdgeContentLayout
: จัดตำแหน่งเนื้อหาบริเวณขอบของหน้าจอ เช่นCircularProgressIndicator
เมื่อใช้เลย์เอาต์นี้ เนื้อหาภายในเลย์เอาต์ จะมีระยะขอบและระยะห่างจากขอบที่เหมาะสมโดยอัตโนมัติ
ส่วนโค้ง
ระบบรองรับคอนเทนเนอร์ย่อย 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 ประเภท ได้แก่
เช่น ทำให้ "โลก" เป็นตัวเอียง ในโหมด "สวัสดีโลก" ไทล์และแทรก รูปภาพระหว่างคำ ดังที่ปรากฏในตัวอย่างโค้ดต่อไปนี้
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() ); }
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ย้ายข้อมูลไปยังเนมสเปซ ProtoLayout
ConstraintLayout
ในการเขียน- สร้างการ์ดการตั้งค่าด่วนที่กำหนดเองสำหรับแอป