Apps foundation

การพัฒนาการ์ดเป็นวิดเจ็ต Wear โดยใช้ Jetpack Glance และ Remote Compose

ลำโพง

  • François Deschênes

    ผู้จัดการผลิตภัณฑ์

  • Yuri Schimke

    วิศวกรซอฟต์แวร์

เกี่ยวกับ

เกี่ยวกับการเสวนา

ในเซสชันนี้ เราจะเจาะลึกด้านเทคนิคเกี่ยวกับวิวัฒนาการจากไทล์แบบเต็มหน้าจอไปสู่วิดเจ็ต Wear แบบไดนามิกที่มีความสูงบางส่วน

เราจะสำรวจประโยชน์ทางเทคนิคของ Jetpack Glance API แบบรวมและเครื่องมือ Remote Compose ใหม่ โดยจะอธิบายรายละเอียดว่า API และเครื่องมือดังกล่าวสอดคล้องกับ Modern Android Development อย่างไร

สุดท้าย เราจะแชร์คำแนะนำล่าสุดเกี่ยวกับ UX และอธิบายกลยุทธ์การย้ายข้อมูลที่นำไปใช้ได้จริงเพื่อช่วยคุณสร้าง UI ที่แสดงข้อมูลแบบคร่าวๆ รุ่นถัดไป

สรุป

  • Wear OS กำลังพัฒนาการ์ดแบบเต็มหน้าจอให้เป็นวิดเจ็ต Wear ที่สร้างด้วย Jetpack Glance และขับเคลื่อนโดย Remote Compose
  • Remote Compose ใช้คอมไพเลอร์และรันไทม์เดียวกันกับ Jetpack Compose UI ขณะเดียวกันก็แยก UI ออกจากกระบวนการของแอปได้อย่างปลอดภัย
  • คอนเทนเนอร์ขนาดเล็กและขนาดใหญ่จะสอดคล้องกับรูปแบบตารางกริดบนอุปกรณ์เคลื่อนที่ ส่วน Jetpack Glance Wear API จะรักษาความเข้ากันได้แบบย้อนหลังจนถึง Wear 4
  • การย้ายข้อมูลการ์ดที่มีอยู่ไปยังวิดเจ็ตสามารถใช้กลยุทธ์บริการคู่ที่แนะนำหรือบริการความเข้ากันได้รายการเดียวก็ได้

ทักษะ

แหล่งข้อมูล

Gemini Notebook

หัวข้อ

  • wear-os
  • wear-widgets
  • jetpack-glance
  • remote-compose
  • tiles-migration
  • jetpack-compose

ข้อความถอดเสียง

บทนำ

  • สวัสดีทุกคน

  • ผมชื่อ Frank เป็นหัวหน้าทีมประสบการณ์การใช้งานที่เข้าถึงได้ง่ายสำหรับ Wear OS

  • นาฬิกาเป็นอุปกรณ์สำคัญที่อยู่ติดตัวผู้ใช้ตลอดทั้งวัน และวันนี้เราจะแนะนำวิธีใช้ประโยชน์จากประสบการณ์การใช้งานวิดเจ็ต Wear ใหม่

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

  • วันนี้ Yuri เพื่อนร่วมงานและเพื่อนร่วมโต๊ะที่ยอดเยี่ยมของฉันจะมาร่วมพูดคุยบนเวทีเพื่อเจาะลึกถึงวิธีการที่เรากำลังทำสิ่งนี้

  • สวัสดี ฉันชื่อ Yuri Schimke

  • ฉันเป็นวิศวกรในทีม Wear OS และงานหลักของฉันคือการทำงานกับ Remote Compose API

  • วันนี้ผมจะมาแนะนำ Remote Compose ให้คุณรู้จักคร่าวๆ และพูดถึงกระบวนการย้ายข้อมูลจากไทล์ไปยังวิดเจ็ต Wear ด้วย

  • หลังจากนี้ฉันจะขอส่งต่อให้ Frank

การพัฒนาการ์ดเป็นวิดเจ็ต Wear

  • เยี่ยมมาก

  • ขอบคุณ Yuri

  • เรากำลังนำข้อมือเข้าสู่ระบบนิเวศวิดเจ็ต Android แบบรวมอย่างเป็นทางการด้วยการพัฒนาการ์ดแบบเต็มหน้าจอให้เป็นวิดเจ็ต Wear

  • และเนื่องจากตอนนี้ประสบการณ์เหล่านี้สร้างขึ้นโดยใช้ Jetpack Glance คุณจึงเห็นได้ว่าประสบการณ์เหล่านี้ใช้โครงสร้างพื้นฐานเดียวกันกับที่ใช้สำหรับวิดเจ็ตบนอุปกรณ์เคลื่อนที่

  • คุณจะเห็นว่าการสร้างแอปสำหรับ Wear จะยิ่งคุ้นเคยมากขึ้นในอนาคต

ภาพรวมของ Remote Compose

  • เรากำลังพัฒนา UI Stack ซึ่งเป็น UI Stack พื้นฐานเพื่อขับเคลื่อนประสบการณ์เหล่านี้

  • วิดเจ็ต Wear ทำงานด้วย Remote Compose ซึ่งเป็นเฟรมเวิร์ก Android ใหม่สำหรับ UI ระยะไกล

  • ซึ่งหมายความว่าในที่สุดคุณก็สามารถใช้ API แบบประกาศที่สอดคล้องกับ Jetpack Compose อย่างใกล้ชิดเพื่อสร้างประสบการณ์การใช้งานนอกแอป เช่น วิดเจ็ต

  • Remote Compose นำกราฟิกที่ทันสมัยและเลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์มาสู่วิดเจ็ต พร้อมทั้งรับประกันประสิทธิภาพและการประหยัดแบตเตอรี่

  • และด้วยการแยก UI ออกจากกระบวนการของแอปพลิเคชัน วิดเจ็ตของคุณจะได้รับการจัดเรียงอย่างปลอดภัยและแสดงผลได้ง่ายในอุปกรณ์ Android ที่หลากหลาย ขออภัย

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

ขนาดเลย์เอาต์และความเข้ากันได้แบบย้อนหลัง

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

  • โดยออกแบบมาให้สอดคล้องกับรูปแบบวิดเจ็ตแบบตารางขนาด 2x1 และ 2x2 ที่คุณคุ้นเคยจากการสร้างวิดเจ็ตบนอุปกรณ์เคลื่อนที่

  • และตั้งแต่ Wear 7 เป็นต้นไปในผู้ผลิตฮาร์ดแวร์บางราย วิดเจ็ต Wear จะอยู่ในถาดที่เลื่อนในแนวตั้งควบคู่ไปกับวิดเจ็ตของแอปอื่นๆ

  • ตัวอย่างเช่น วิดเจ็ต Wear บน Samsung Galaxy Watch จะมีลักษณะดังนี้

  • สถาปัตยกรรมของแพลตฟอร์มสร้างขึ้นเพื่อรองรับถาดที่เลื่อนในแนวตั้ง เนื่องจากผู้ผลิตฮาร์ดแวร์จะใช้รูปแบบนี้ในอนาคต

  • และคุณไม่ต้องกังวลว่าจะทิ้งผู้ใช้หรือผู้ใช้เดิมไว้ข้างหลัง

  • API ของ Jetpack Glance Wear ออกแบบมาเพื่อรองรับความเข้ากันได้แบบย้อนหลังจนถึง Wear 4

  • ในอุปกรณ์รุ่นเก่าที่รองรับถาดวิดเจ็ตหรือการ์ดแนวนอน ระบบจะจัดการให้คุณ

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

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

กลยุทธ์การย้ายข้อมูลสำหรับไทล์ที่มีอยู่

  • ขอบคุณ Frank

  • หากคุณสร้างวิดเจ็ต Wear ใหม่ตั้งแต่ต้น ก็ทำได้ง่ายๆ

  • คุณเพียงแค่กำหนด GlanceWearWidgetService และสร้าง UI โดยใช้ Remote Compose

  • แต่หากแอปของคุณมีไทล์ในเวอร์ชันที่ใช้งานจริงอยู่แล้ว คุณจะต้องย้ายข้อมูลทั้งบริการ, UI และข้อมูล

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

  • สำหรับบริการ คุณสามารถเลือกกลยุทธ์ได้ 2 แบบ ได้แก่ บริการคู่หรือบริการเดียว

  • เราขอแนะนำให้ใช้บริการแบบคู่ ซึ่งคุณจะเก็บ TileService ที่มีอยู่ไว้สำหรับอุปกรณ์ Wear OS รุ่นเก่า และเพิ่ม GlanceWearWidgetService ใหม่สำหรับ Wear OS 7 ขึ้นไป

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

  • ไม่ว่าจะเลือกวิธีใด คุณก็จะยังคงเข้าถึงผู้ใช้ได้

  • แต่จะส่งผลต่อโค้ดที่คุณจะใช้ต่อไปเท่านั้น

  • และเราเพิ่งเผยแพร่เอกสารประกอบที่ครอบคลุมในเว็บไซต์นักพัฒนาแอป Android ซึ่งให้รายละเอียดเกี่ยวกับวิธีและเวลาที่ควรใช้ทั้ง 2 รูปแบบนี้อย่างชัดเจน

  • ลองดูเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับกลยุทธ์ที่เหมาะกับแอปของคุณมากที่สุด

การสร้าง UI ด้วย Remote Compose

  • ทีนี้เรามาพูดถึงเลเยอร์ UI กัน

  • เมื่อย้ายข้อมูล โมเดลความคิดของคุณจะเปลี่ยนไป

  • ก่อนหน้านี้ การ์ดใช้ ProtoLayout ซึ่งเป็นไลบรารีที่สร้างขึ้นสำหรับการ์ด Wear โดยเฉพาะ

  • ในทางกลับกัน Wear Widgets จะสร้างขึ้นจาก Remote Compose

  • Remote Compose ใช้พื้นฐานเดียวกันกับ Jetpack Compose UI โดยใช้คอมไพเลอร์หลักและรันไทม์เดียวกัน

  • และได้รับการออกแบบมาให้คุ้นเคย โดยใกล้เคียงกับไลบรารี Compose UI เช่น Foundation และ Material 3

  • แต่แทนที่จะเป็นกล่อง คอลัมน์ หรือข้อความ คุณจะสลับเป็น RemoteBox, RemoteColumn หรือ RemoteText แทน

  • ในกรณีนี้ คุณจะคุ้นเคยกับการเขียน "remote" เป็นอย่างมาก

  • นอกจากนี้ เพื่อเพิ่มความเร็วให้เวิร์กโฟลว์ เราได้รวมคอมโพเนนต์ Remote Compose ที่พร้อมใช้งานครบชุดซึ่งออกแบบมาสำหรับวิดเจ็ตโดยเฉพาะ

  • ซึ่งหมายความว่าคุณสามารถปรับการออกแบบ Wear Material 3 ที่มีอยู่ รวมถึงสิ่งที่คุณมีใน Figma ให้เข้ากับวิดเจ็ตได้อย่างง่ายดาย ทำให้ทั้งวิศวกรและนักออกแบบคุ้นเคยกับวิดเจ็ตนี้

  • มาดูตัวอย่างที่ชัดเจนกันว่าเฟรมเวิร์กเหล่านี้สอดคล้องกันอย่างไร

  • เราจะสร้างคอมโพเนนต์แอปของเราเองบนปุ่มสวิตช์ Material 3

  • ทางด้านซ้าย เรามีคอมโพเนนต์ Wear Compose มาตรฐานที่คุณจะเขียนภายในแอป และทางด้านขวาคือเวอร์ชัน Remote Compose

    // Wear Compose
    @Composable
    fun HistoryEraserButton(
      onClick: () -> Unit,
      modifier: Modifier = Modifier,
      checked: Boolean = true,
      onCheckedChange: (Boolean) -> Unit = {},
    )
    // Wear RemoteCompose
    @RemoteComposable
    @Composable
    fun RemoteHistoryEraserButton(
      onClick: Action,
      modifier: RemoteModifier = RemoteModifier,
      checked: RemoteBoolean = true.rb,
      onCheckedChange: Action = Action.Empty,
    )
  • สังเกตว่ารูปแบบมีความคล้ายกันอย่างไร

  • อย่างไรก็ตาม เมื่อเขียนโค้ด Remote Compose คุณจะใช้คำอธิบายประกอบ RemoteComposable

  • และในกรณีที่คุณใช้พารามิเตอร์ที่คุ้นเคย เช่น ตัวแก้ไขและบูลีน พารามิเตอร์เหล่านั้นจะมีประเภท Remote Compose ที่เทียบเท่ากัน เช่น RemoteModifier และ RemoteBoolean

  • และคุณใช้การดำเนินการแทน Lambda

  • คุณจะต้องประกาศการดำเนินการ เช่น การเปิดใช้งาน Intent รอดำเนินการ การเรียกใช้บริการ หรือการอัปเดตค่า แทนที่จะกำหนดการเรียกใช้โค้ดเพื่อเรียกใช้ภายใน Lambda

  • มาดูที่ส่วนเนื้อหาของคอมโพเนนต์กัน

  • คุณจะสังเกตเห็นว่าแม้แต่ธีมก็สอดคล้องกัน

  • คุณสามารถใช้รูปแบบสี Material 3 กับคอมโพเนนต์ Remote Compose ได้เหมือนกับที่ทำใน Compose มาตรฐาน ซึ่งจะช่วยให้วิดเจ็ตตรงกับการสร้างแบรนด์ของแอปทุกประการ

    // Wear Compose
      val colors = MaterialTheme.colorScheme
      SplitSwitchButton(
        checked = checked,
        onCheckedChange = onCheckedChange,
        toggleContentDescription = "Arm Eraser",
        onContainerClick = onClick,
        modifier = modifier.fillMaxWidth(),
        colors =
          SwitchButtonDefaults.splitSwitchButtonColors(
            checkedContainerColor = colors.errorContainer, …
          ),
        label = { Text("History Eraser") },
        secondaryLabel = { Text("Don't touch it!") },
      )
    // Wear RemoteCompose
      val colors = RemoteMaterialTheme.colorScheme
      RemoteSplitSwitchButton(
        checked = checked,
        onCheckedChange = onCheckedChange,
        toggleContentDescription = "Arm Eraser".rs,
        onContainerClick = onClick,
        modifier = modifier.fillMaxWidth(),
        colors =
          RemoteSplitSwitchButtonDefaults.splitSwitchButtonColors(
            checkedContainerColor = colors.errorContainer, …
          ),
        label = { RemoteText("History Eraser".rs) },
        secondaryLabel = { RemoteText("Don't touch it!".rs) },
      )
  • และสุดท้าย มาดูผลลัพธ์กัน UI ที่ได้จะเป็นไปตามที่คุณคาดหวัง นั่นคือปุ่มเปิด/ปิดแบบเคลื่อนไหวที่สะอาดตาและตอบสนองได้ดี

การรองรับตัวอย่างการเขียนสำหรับวิดเจ็ต

  • บอกความแตกต่างได้ยาก

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

  • เนื่องจากวิดเจ็ตขึ้นอยู่กับข้อจำกัดของคอนเทนเนอร์เฉพาะ OEM เช่น ขนาด รูปร่าง ระยะห่างจากขอบ รัศมีมุม เราจึงสร้างขึ้นจากการกำกับเนื้อหาตัวอย่างมาตรฐาน แต่มีผู้ให้บริการพารามิเตอร์เพิ่มเติมเพื่อแทรกการกำหนดค่าเหล่านี้

    @Preview(name = "Squircle Preview", device = "spec:width=1000dp,height=1000dp,dpi=320")
    @Composable
    fun WeatherWidgetSquirclePreview(
        @PreviewParameter(SquircleAllWidgetPreviewParams::class) params: WearWidgetParams
    ) = WearWidgetPreview(MockWeatherWidget(65, WeatherCondition.CLOUDY), params)
    
    @Preview(name = "Round Preview", device = "spec:width=1000dp,height=1000dp,dpi=320")
    @Composable
    fun WeatherWidgetRoundPreview(
        @PreviewParameter(RoundAllWidgetPreviewParams::class) params: WearWidgetParams
    ) = WearWidgetPreview(MockWeatherWidget(65, WeatherCondition.CLOUDY), params)
  • ไลบรารีนี้มีการติดตั้งใช้งานผู้ให้บริการ PreviewParameter ที่กำหนดค่าไว้ล่วงหน้าซึ่งตรงกับอุปกรณ์ Wear OS จริง

  • คำอธิบายประกอบตัวอย่างเหล่านี้ช่วยให้คุณยืนยันเลย์เอาต์ในรูปทรงฮาร์ดแวร์ที่แตกต่างกันได้อย่างง่ายดาย

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

    @Preview(name = "Widget Picker Preview", device = "spec:width=1000dp,height=1000dp,dpi=320")
    @Composable
    fun WeatherWidgetRectangularPreview(
        @PreviewParameter(RectangularAllWidgetPreviewParams::class) params: WearWidgetParams
    ) = WearWidgetPreview(MockWeatherWidget(65, WeatherCondition.CLOUDY), params)
  • ไลบรารีมีพารามิเตอร์สำหรับรูปร่างตัวอย่างสี่เหลี่ยมผืนผ้าซึ่งจำลองคอนเทนเนอร์สี่เหลี่ยมผืนผ้าแบบเต็มที่ไม่มีการครอบตัด

ตัวอย่างเครื่องมือการติดตั้งใช้งานและการย้ายข้อมูล

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

  • เราจะแสดงวิธีเพิ่มวิดเจ็ตสื่อทั้งเวอร์ชันขนาดเล็กและขนาดใหญ่

  • ดูข้อมูลใน GitHub เพื่อดูการเปรียบเทียบโค้ด ProtoLayout เดิมกับการติดตั้งใช้งาน Remote Compose ใหม่แบบเทียบกัน

  • เรามั่นใจว่าคุณจะต้องชอบ

  • สุดท้ายนี้ เราคงจะพูดว่ามีการพัฒนานวัตกรรมได้ไม่เต็มปากหากไม่พูดถึง AI

  • เราได้เผยแพร่ทักษะการย้ายข้อมูลจากไทล์ไปยังวิดเจ็ตใหม่บน GitHub เพื่อเร่งการย้ายข้อมูลของคุณ

  • คุณสามารถใช้เครื่องมือนี้กับ Agent ที่คุณเลือก หรือจะเพิ่มลงใน Android Studio โดยตรงโดยใช้ Android CLI ก็ได้

    android skills add wear-widgets
    android skills add --all
  • ตอนนี้เราจะส่งต่อให้ François สรุปสิ่งต่างๆ

สรุปและปิดท้าย

  • ขอขอบคุณ

  • ขอบคุณ Yuri

  • ดังนั้นคุณจะเห็นได้ว่าการพัฒนาการ์ดให้เป็นวิดเจ็ต Wear เป็นกระบวนการที่ตรงไปตรงมามาก

  • สรุปคือ การย้ายข้อมูลไปยัง Jetpack Glance Wear และ Remote Compose ไม่ใช่แค่การอัปเดต UI เท่านั้น แต่เป็นการเข้าร่วมระบบนิเวศวิดเจ็ต Android ที่เป็นหนึ่งเดียวกันมากขึ้น

  • ตอนนี้คุณสามารถสร้างวิดเจ็ตที่สวยงามและเข้ากันได้แบบย้อนหลังโดยใช้เฟรมเวิร์กแบบประกาศที่ทันสมัยซึ่งสอดคล้องกับ Jetpack Compose อย่างสมบูรณ์

  • คุณเริ่มย้ายข้อมูลการ์ดได้ตั้งแต่วันนี้ โดยไปที่คู่มือเริ่มต้นใช้งานในเว็บไซต์ของนักพัฒนาแอป Android เพื่อดูรายละเอียดทั้งหมด

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

  • ขอขอบคุณเป็นอย่างยิ่งที่มาร่วมงานกับเราในวันนี้ และหวังว่าคุณจะเพลิดเพลินกับช่วงเวลาที่เหลือของการประชุม

  • ขอขอบคุณ

รหัส

ข้อมูลโค้ด

ข้อมูลโค้ด Kotlin ที่ 06:40 ใน "การสร้าง UI ด้วย Remote Compose"
// Wear Compose
@Composable
fun HistoryEraserButton(
  onClick: () -> Unit,
  modifier: Modifier = Modifier,
  checked: Boolean = true,
  onCheckedChange: (Boolean) -> Unit = {},
)
ข้อมูลโค้ด Kotlin ที่ 06:40 ใน "การสร้าง UI ด้วย Remote Compose"
// Wear RemoteCompose
@RemoteComposable
@Composable
fun RemoteHistoryEraserButton(
  onClick: Action,
  modifier: RemoteModifier = RemoteModifier,
  checked: RemoteBoolean = true.rb,
  onCheckedChange: Action = Action.Empty,
)
ข้อมูลโค้ด Kotlin ที่นาที 07:39 ใน "การสร้าง UI ด้วย Remote Compose"
// Wear Compose
  val colors = MaterialTheme.colorScheme
  SplitSwitchButton(
    checked = checked,
    onCheckedChange = onCheckedChange,
    toggleContentDescription = "Arm Eraser",
    onContainerClick = onClick,
    modifier = modifier.fillMaxWidth(),
    colors =
      SwitchButtonDefaults.splitSwitchButtonColors(
        checkedContainerColor = colors.errorContainer, …
      ),
    label = { Text("History Eraser") },
    secondaryLabel = { Text("Don't touch it!") },
  )
ข้อมูลโค้ด Kotlin ที่ 07:39 ใน "การสร้าง UI ด้วย Remote Compose"
// Wear RemoteCompose
  val colors = RemoteMaterialTheme.colorScheme
  RemoteSplitSwitchButton(
    checked = checked,
    onCheckedChange = onCheckedChange,
    toggleContentDescription = "Arm Eraser".rs,
    onContainerClick = onClick,
    modifier = modifier.fillMaxWidth(),
    colors =
      RemoteSplitSwitchButtonDefaults.splitSwitchButtonColors(
        checkedContainerColor = colors.errorContainer, …
      ),
    label = { RemoteText("History Eraser".rs) },
    secondaryLabel = { RemoteText("Don't touch it!".rs) },
  )
ข้อมูลโค้ด Kotlin ที่นาที 08:20 ใน "การรองรับตัวอย่าง Compose สำหรับวิดเจ็ต"
@Preview(name = "Squircle Preview", device = "spec:width=1000dp,height=1000dp,dpi=320")
@Composable
fun WeatherWidgetSquirclePreview(
    @PreviewParameter(SquircleAllWidgetPreviewParams::class) params: WearWidgetParams
) = WearWidgetPreview(MockWeatherWidget(65, WeatherCondition.CLOUDY), params)

@Preview(name = "Round Preview", device = "spec:width=1000dp,height=1000dp,dpi=320")
@Composable
fun WeatherWidgetRoundPreview(
    @PreviewParameter(RoundAllWidgetPreviewParams::class) params: WearWidgetParams
) = WearWidgetPreview(MockWeatherWidget(65, WeatherCondition.CLOUDY), params)
ข้อมูลโค้ด Kotlin ที่นาที 08:58 ใน "การรองรับตัวอย่าง Compose สำหรับวิดเจ็ต"
@Preview(name = "Widget Picker Preview", device = "spec:width=1000dp,height=1000dp,dpi=320")
@Composable
fun WeatherWidgetRectangularPreview(
    @PreviewParameter(RectangularAllWidgetPreviewParams::class) params: WearWidgetParams
) = WearWidgetPreview(MockWeatherWidget(65, WeatherCondition.CLOUDY), params)
Shell snippet at 09:58 in "Sample implementation and migration tools"
android skills add wear-widgets
android skills add --all