強化小工具

試試 Compose 方式
Jetpack Compose 是 Android 推薦的 UI 工具包。瞭解如何使用 Compose 樣式的 API 建構小工具。

本頁說明 Android 12 (API 級別 31) 以上版本提供的選用小工具強化功能。這些功能為選用功能,但實作方式簡單明瞭,可提升使用者的小工具體驗。

使用動態色彩

從 Android 12 開始,小工具可以使用裝置主題顏色做為按鈕、背景和其他元件的顏色。這樣一來,不同小工具之間的轉場效果會更流暢,且整體一致性更高。

動態色彩的實作方式有兩種:

在根版面配置中設定主題後,您可以在根版面配置或任何子項中使用常見的顏色屬性,挑選動態顏色。

可用的顏色屬性範例如下:

  • ?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 助理在收到相關語音指令時顯示小工具。將小工具設為回應內建意圖 (BII),應用程式就能在 Android 和 Android Auto 等 Google 助理介面上主動顯示小工具。使用者可以釘選小工具,將 Google 助理顯示的小工具釘選到啟動器,鼓勵日後互動。

舉例來說,您可以為運動應用程式設定運動摘要小工具,以滿足觸發 GET_EXERCISE_OBSERVATION BII 的使用者語音指令。當使用者提出「Ok Google,根據範例應用程式的數據,我這個禮拜跑了幾英里?」等要求,觸發這個 BII 時,Google 助理就會主動顯示小工具。

有數十個 BII 涵蓋多種使用者互動類別,幾乎任何 Android 應用程式都能透過這些 BII 強化語音小工具。如要開始使用,請參閱「整合應用程式動作與 Android 小工具」。

改善應用程式的小工具選擇器體驗

Android 12 可讓您新增縮放的小工具預覽畫面和小工具說明。Android 15 可讓您透過產生的動態小工具預覽畫面,提升應用程式的小工具挑選器體驗。

如要提升應用程式的小工具選擇器體驗,請在 Android 15 以上版本裝置上提供產生的小工具預覽畫面,在 Android 12 至 Android 14 裝置上提供縮放的小工具預覽畫面 (方法是指定 previewLayout),並在舊版裝置上提供 previewImage

在小工具挑選器中新增產生的小工具預覽畫面

應用程式必須在模組 build.gradle 檔案中將 compileSdk 值設為 35 以上,才能在 Android 15 以上版本的裝置上,向小工具挑選器提供 RemoteViews。也就是說,應用程式可以更新挑選器中的內容,更貼近使用者所見。

應用程式可以使用 AppWidgetManagersetWidgetPreviewgetWidgetPreview 方法,以最新且個人化的資訊更新小工具的外觀。

使用 Jetpack Glance 產生更新的預覽畫面

Glance.compose 會執行一個組合,因此可組合函式主體中不會使用任何暫停函式、流程或類似的非同步呼叫。請改用常數資料。

下列範例使用 Jetpack Glance 生成更新後的預覽畫面。如要讓 setWidgetPreview 在這個程式碼片段中顯示為方法,compileSdk 建構設定必須為 35 以上。

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

產生不含 Jetpack Glance 的更新版預覽畫面

你可以在沒有微光模式的情況下使用 RemoteViews。以下範例會載入 XML 小工具版面配置資源,並設為預覽畫面。如要讓 setWidgetPreview 在這個程式碼片段中顯示為方法,compileSdk 建構設定必須為 35 以上。

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

在小工具挑選器中新增可縮放的小工具預覽畫面

從 Android 12 開始,小工具挑選器中顯示的小工具預覽畫面可縮放。您提供的 XML 版面配置會設為小工具的預設大小。先前,小工具預覽畫面是靜態可繪資源,在某些情況下,預覽畫面會無法準確反映小工具新增至主畫面時的顯示方式。

如要實作可縮放的小工具預覽畫面,請使用 appwidget-provider 元素的 previewLayout 屬性來提供 XML 版面配置:

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

建議使用與實際小工具相同的版面配置,並提供實際的預設值或測試值。大多數應用程式都使用相同的 previewLayoutinitialLayout。如需建立準確預覽版面配置的指引,請參閱本頁面的下一節。

建議您同時指定 previewLayoutpreviewImage 屬性,這樣一來,如果使用者的裝置不支援 previewLayout,應用程式就能改用 previewImagepreviewLayout 屬性的優先順序高於 previewImage 屬性。

建議採用哪些方法,才能建構準確的預覽畫面

如要實作可縮放的小工具預覽畫面,請使用 appwidget-provider 元素的 previewLayout 屬性提供 XML 版面配置:

<appwidget-provider
    ...
    android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>
顯示小工具預覽畫面的圖片
圖 3. 小工具預覽畫面預設會顯示在 3x3 區域,但由於 XML 版面配置,因此可以顯示在 3x1 區域。

如要顯示準確的預覽畫面,請完成下列步驟,直接提供含有預設值的實際小工具版面配置:

  • TextView 元素設定 android:text="@string/my_widget_item_fake_1"

  • ImageView 元件設定預設或預留位置圖片/圖示,例如 android:src="@drawable/my_widget_icon"

如果沒有預設值,預覽畫面可能會顯示不正確或空白的值。這種做法的重要優點是,您可以提供本地化的預覽內容。

如要瞭解包含 ListViewGridViewStackView 的複雜預覽畫面建議做法,請參閱「建構包含動態項目的準確預覽畫面」一文。

可縮放的小工具預覽畫面,提供回溯相容性

如要在 Android 11 (API 級別 30) 以下版本的動態磚選擇器中顯示動態磚預覽畫面,請指定 previewImage 屬性。

如果變更小工具的外觀,請更新預覽圖片。

為小工具命名

在小工具挑選器中顯示的小工具名稱不得重複。

系統會從 AndroidManifest.xml 檔案中,小工具 receiver 元素的 label 屬性載入小工具名稱。

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

新增小工具說明

從 Android 12 開始,您可以為小工具挑選器提供說明,以便顯示小工具。

圖片:顯示小工具挑選器,其中顯示小工具和說明
圖 4. 小工具挑選器範例,顯示小工具及其說明。

使用 &lt;appwidget-provider&gt; 元素的 description 屬性,提供小工具的說明:

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

您可以在舊版 Android 上使用 descriptionRes 屬性,但小工具挑選器會忽略該屬性。

啟用更流暢的轉場效果

從 Android 12 開始,啟動器會在使用者透過小工具啟動應用程式時,提供更流暢的轉場效果。

如要啟用這項改良的轉場效果,請使用 @android:id/backgroundandroid.R.id.background 識別背景元素:

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

您的應用程式可以在舊版 Android 上使用 @android:id/background,不會發生錯誤,但系統會忽略這項功能。

在執行階段修改 RemoteViews

從 Android 12 開始,您可以利用多種 RemoteViews 方法,在執行階段修改 RemoteViews 屬性。如需新增方法的完整清單,請參閱 RemoteViews API 參考資料。

以下程式碼範例說明如何使用其中幾種方法。

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);