ปรับปรุงวิดเจ็ต

หน้านี้มีรายละเอียดเกี่ยวกับการปรับปรุงวิดเจ็ตที่ไม่บังคับซึ่งพร้อมใช้งานตั้งแต่ Android 12 (API ระดับ 31) ฟีเจอร์เหล่านี้เป็นฟีเจอร์ที่ไม่บังคับ แต่ใช้งานได้ง่ายและช่วยปรับปรุงประสบการณ์การใช้งานวิดเจ็ตของผู้ใช้

ใช้สีแบบไดนามิก

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

คุณสร้างสีแบบไดนามิกได้ 2 วิธีดังนี้

  • ใช้ธีมเริ่มต้นของระบบ (@android:style/Theme.DeviceDefault.DayNight) ในเลย์เอาต์รูท

  • ใช้ธีม Material 3 (Theme.Material3.DynamicColors.DayNight) จากไลบรารี Material Components for Android ซึ่งพร้อมใช้งานใน Material Components for Android v1.6.0 เป็นต้นไป

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

ตัวอย่างแอตทริบิวต์สีที่คุณใช้ได้มีดังนี้

  • ?attr/primary
  • ?attr/primaryContainer
  • ?attr/onPrimary
  • ?attr/onPrimaryContainer

ในตัวอย่างนี้ที่ใช้ธีม Material 3 สีของธีมอุปกรณ์คือ "สีม่วง" สีที่ใช้เน้นและพื้นหลังของวิดเจ็ตจะปรับให้เข้ากับโหมดสว่างและโหมดมืด ดังที่แสดงในรูปภาพ 1 และ 2

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="?attr/colorPrimaryContainer"
  android:theme="@style/Theme.Material3.DynamicColors.DayNight">

  <ImageView
    ...
    app:tint="?attr/colorPrimaryContainer"
    android:src="@drawable/ic_partly_cloudy" />

    <!-- Other widget content. -->

</LinearLayout>
วิดเจ็ตในธีมโหมดสว่าง
รูปที่ 1 วิดเจ็ตในธีมสว่าง
วิดเจ็ตในธีมโหมดมืด
รูปที่ 2 วิดเจ็ตในธีมมืด

ความเข้ากันได้แบบย้อนหลังสำหรับสีแบบไดนามิก

สีแบบไดนามิกใช้ได้ในอุปกรณ์ที่ใช้ Android 12 ขึ้นไปเท่านั้น หากต้องการระบุธีมที่กำหนดเองสำหรับเวอร์ชันที่ต่ำกว่า ให้สร้างธีมเริ่มต้นที่มีสีที่กำหนดเองและตัวระบุใหม่ (values-v31) โดยใช้แอตทริบิวต์ธีมเริ่มต้น

ตัวอย่างการใช้ธีม Material 3 มีดังนี้

/values/styles.xml

<resources>
  <style name="MyWidgetTheme" parent="Theme.Material3.DynamicColors.DayNight">
    <!-- Override default colorBackground attribute with custom color. -->
    <item name="android:colorBackground">@color/my_background_color</item>

    <!-- Add other colors/attributes. -->

  </style>
</resources>

/values-v31/styles.xml

<resources>
  <!-- Do not override any color attribute. -->
  <style name="MyWidgetTheme" parent="Theme.Material3.DynamicColors.DayNight" />
</resources>

/layout/my_widget_layout.xml

<resources>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:background="?android:attr/colorBackground"
    android:theme="@style/MyWidgetTheme" />
</resources>

เปิดใช้การรองรับเสียง

การดำเนินการของแอปช่วยให้ Google Assistant แสดงวิดเจ็ตเพื่อตอบสนองต่อคำสั่งเสียงที่เกี่ยวข้องของผู้ใช้ การกำหนดค่าวิดเจ็ตให้ตอบสนองต่อ Intent ในตัว (BIIs) จะช่วยให้แอปแสดงวิดเจ็ตในแพลตฟอร์ม Assistant เช่น Android และ Android Auto ได้แบบเชิงรุก ผู้ใช้มีตัวเลือกในการปักหมุดวิดเจ็ตที่ Assistant แสดงไว้ในตัวเปิดแอป ซึ่งจะช่วยกระตุ้นการมีส่วนร่วมในอนาคต

เช่น คุณสามารถกําหนดค่าวิดเจ็ตข้อมูลสรุปการออกกําลังกายสําหรับแอปการออกกําลังกายเพื่อตอบสนองคําสั่งเสียงของผู้ใช้ที่ทริกเกอร์ GET_EXERCISE_OBSERVATION ของ BI Assistant จะแสดงวิดเจ็ตของคุณอย่างสม่ำเสมอเมื่อผู้ใช้เรียกใช้ BII นี้ด้วยการส่งคําขอ เช่น "Ok Google ฉันวิ่งกี่ไมล์ในสัปดาห์นี้ใน ExampleApp"

มี BIIs หลายสิบรายการที่ครอบคลุมการโต้ตอบของผู้ใช้หลายหมวดหมู่ ซึ่งช่วยให้แอป Android เกือบทุกแอปปรับปรุงวิดเจ็ตสำหรับเสียงได้ หากต้องการเริ่มต้นใช้งาน โปรดดูหัวข้อผสานรวม App Actions กับวิดเจ็ต Android

ปรับปรุงประสบการณ์การใช้งานเครื่องมือเลือกวิดเจ็ตของแอป

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

หากต้องการปรับปรุงประสบการณ์การใช้งานเครื่องมือเลือกวิดเจ็ตของแอป ให้แสดงตัวอย่างวิดเจ็ตที่สร้างขึ้นบนอุปกรณ์ Android 15 ขึ้นไป ตัวอย่างวิดเจ็ตที่ปรับขนาด (โดยระบุ previewLayout) สำหรับอุปกรณ์ Android 12 ถึง Android 14 และ previewImage สำหรับเวอร์ชันก่อนหน้า

เพิ่มตัวอย่างวิดเจ็ตที่สร้างขึ้นลงในเครื่องมือเลือกวิดเจ็ต

แอปต้องตั้งค่า compileSdk เป็น 35 ขึ้นไปในไฟล์ข้อบังคับ build.gradle จึงจะระบุ RemoteViews ให้กับเครื่องมือเลือกวิดเจ็ตในอุปกรณ์ Android 15 ขึ้นไปได้ ซึ่งหมายความว่าแอปจะอัปเดตเนื้อหาในเครื่องมือเลือกเพื่อให้แสดงสิ่งที่ผู้ใช้เห็นมากขึ้น

แอปสามารถใช้เมธอด AppWidgetManager, setWidgetPreview และgetWidgetPreview เพื่ออัปเดตลักษณะที่ปรากฏของวิดเจ็ตด้วยข้อมูลล่าสุดและข้อมูลเฉพาะบุคคล

สร้างตัวอย่างที่อัปเดตแล้วด้วย Jetpack Glance

Glance.compose เรียกใช้การคอมโพสิชัน 1 รายการ ดังนั้นจึงไม่ใช้ฟังก์ชันที่ระงับ ฟิวเจอร์ หรือการเรียกแบบแอสซิงค์ที่คล้ายกันในเนื้อหาของคอมโพสิชัน แต่ต้องใช้ข้อมูลคงที่แทน

ตัวอย่างต่อไปนี้ใช้ Jetpack Glance เพื่อสร้างตัวอย่างที่อัปเดตแล้ว compileSdk ต้องใช้การตั้งค่าบิลด์ 35 ขึ้นไปเพื่อให้ setWidgetPreview แสดงเป็นเมธอดในสนิปเพลตนี้

AppWidgetManager.getInstance(appContext).setWidgetPreview(
    ComponentName(
        appContext,
        ExampleAppWidgetReceiver::class.java
    ),
    AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
    ExampleAppWidget().compose(
        context = appContext
    ),
)

สร้างตัวอย่างที่อัปเดตแล้วโดยไม่มีข้อมูลโดยย่อของ Jetpack

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

AppWidgetManager.getInstance(appContext).setWidgetPreview(
    ComponentName(
        appContext,
        ExampleAppWidgetReceiver::class.java
    ),
    AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
    RemoteViews("com.example", R.layout.widget_preview)
)

เพิ่มตัวอย่างวิดเจ็ตที่ปรับขนาดได้ลงในเครื่องมือเลือกวิดเจ็ต

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

หากต้องการใช้ตัวอย่างวิดเจ็ตที่ปรับขนาดได้ ให้ใช้แอตทริบิวต์ previewLayout ขององค์ประกอบ appwidget-provider เพื่อระบุเลย์เอาต์ XML แทน

<appwidget-provider
    android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>

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

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

แนวทางที่แนะนำในการสร้างตัวอย่างที่ถูกต้อง

หากต้องการใช้ตัวอย่างวิดเจ็ตที่ปรับขนาดได้ ให้ใช้แอตทริบิวต์ previewLayout ขององค์ประกอบ appwidget-provider เพื่อระบุเลย์เอาต์ XML ดังนี้

<appwidget-provider
    ...
    android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>
รูปภาพที่แสดงตัวอย่างวิดเจ็ต
รูปที่ 3 ตัวอย่างวิดเจ็ตที่ปรากฏในพื้นที่ 3x3 โดยค่าเริ่มต้น แต่สามารถใส่ในพื้นที่ 3x1 ได้เนื่องจากเลย์เอาต์ XML

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

  • การตั้งค่า android:text="@string/my_widget_item_fake_1" สำหรับองค์ประกอบ TextView

  • การตั้งค่ารูปภาพหรือไอคอนเริ่มต้นหรือตัวยึดตําแหน่ง เช่น android:src="@drawable/my_widget_icon" สําหรับคอมโพเนนต์ ImageView

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

ดูรายละเอียดเกี่ยวกับแนวทางที่แนะนำสำหรับตัวอย่างที่ซับซ้อนมากขึ้นซึ่งมี ListView, GridView หรือ StackView ได้ที่สร้างตัวอย่างที่ถูกต้องซึ่งมีรายการแบบไดนามิก

ความเข้ากันได้แบบย้อนหลังกับตัวอย่างวิดเจ็ตที่ปรับขนาดได้

หากต้องการให้เครื่องมือเลือกวิดเจ็ตใน Android 11 (API ระดับ 30) หรือต่ำกว่าแสดงตัวอย่างวิดเจ็ต ให้ระบุแอตทริบิวต์ previewImage

หากคุณเปลี่ยนลักษณะที่ปรากฏของวิดเจ็ต ให้อัปเดตรูปภาพตัวอย่าง

เพิ่มชื่อให้กับวิดเจ็ต

วิดเจ็ตต้องมีชื่อที่ไม่ซ้ำกันเมื่อแสดงในเครื่องมือเลือกวิดเจ็ต

ระบบจะโหลดชื่อวิดเจ็ตจากแอตทริบิวต์ label ขององค์ประกอบ receiver วิดเจ็ตในไฟล์ AndroidManifest.xml

<receiver
    ….
   android:label="Memories">
     ….
</receiver>

เพิ่มคําอธิบายสําหรับวิดเจ็ต

ตั้งแต่ Android 12 เป็นต้นไป ให้ระบุคำอธิบายสำหรับเครื่องมือเลือกวิดเจ็ตที่จะแสดงสำหรับวิดเจ็ต

รูปภาพแสดงเครื่องมือเลือกวิดเจ็ตที่แสดงวิดเจ็ตและคำอธิบาย
รูปที่ 4 ตัวอย่างเครื่องมือเลือกวิดเจ็ตที่แสดงวิดเจ็ตและคำอธิบาย

ระบุคําอธิบายวิดเจ็ตโดยใช้แอตทริบิวต์ description ขององค์ประกอบ &lt;appwidget-provider&gt;

<appwidget-provider
    android:description="@string/my_widget_description">
</appwidget-provider>

คุณใช้แอตทริบิวต์ descriptionRes ใน Android เวอร์ชันก่อนหน้าได้ แต่เครื่องมือเลือกวิดเจ็ตจะไม่สนใจแอตทริบิวต์นี้

ช่วยให้การเปลี่ยนภาพราบรื่นยิ่งขึ้น

ตั้งแต่ Android 12 เป็นต้นไป ตัวเปิดแอปจะเปลี่ยนผ่านได้ราบรื่นขึ้นเมื่อผู้ใช้เปิดแอปจากวิดเจ็ต

หากต้องการเปิดใช้ทรานซิชันที่ปรับปรุงแล้วนี้ ให้ใช้ @android:id/background หรือ android.R.id.background เพื่อระบุองค์ประกอบพื้นหลัง

// Top-level layout of the widget.
<LinearLayout
    android:id="@android:id/background">
</LinearLayout>

แอปของคุณสามารถใช้ @android:id/background ใน Android เวอร์ชันเก่าได้โดยไม่มีปัญหา แต่ระบบจะไม่สนใจ

ใช้การแก้ไขรันไทม์ของ RemoteViews

ตั้งแต่ Android 12 เป็นต้นไป คุณสามารถใช้RemoteViewsเมธอดหลายรายการที่ให้การแก้ไขRemoteViewsแอตทริบิวต์ในรันไทม์ ดูรายการเมธอดทั้งหมดที่เพิ่มแล้วได้ที่ข้อมูลอ้างอิง RemoteViews API

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีใช้เมธอดเหล่านี้ 2-3 วิธี

Kotlin

// Set the colors of a progress bar at runtime.
remoteView.setColorStateList(R.id.progress, "setProgressTintList", createProgressColorStateList())

// Specify exact sizes for margins.
remoteView.setViewLayoutMargin(R.id.text, RemoteViews.MARGIN_END, 8f, TypedValue.COMPLEX_UNIT_DP)

Java

// Set the colors of a progress bar at runtime.
remoteView.setColorStateList(R.id.progress, "setProgressTintList", createProgressColorStateList());

// Specify exact sizes for margins.
remoteView.setViewLayoutMargin(R.id.text, RemoteViews.MARGIN_END, 8f, TypedValue.COMPLEX_UNIT_DP);