ウィジェットを強化する

このページでは、Android 12(API レベル 31)以降で利用できるオプションのウィジェットの機能強化について詳しく説明します。これらの機能は省略可能ですが、実装は簡単で、ユーザーのウィジェット エクスペリエンスを向上させることができます。

ダイナミック カラーを使用する

Android 12 以降のウィジェットでは、ボタンや背景などのコンポーネントにデバイスのテーマカラーを使用できます。これにより、ウィジェット間の遷移がスムーズになり、一貫性が保持されます。

動的色を実現するには、次の 2 つの方法があります。

ルート レイアウトでテーマを設定したら、ルートまたはその子のいずれかの共通のカラー属性を使用して、ダイナミック カラーを取得できます。

使用できる色属性の例を次に示します。

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

マテリアル 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)を含むデフォルトのテーマを作成します。

マテリアル 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>

音声サポートを有効にする

App Actions を使用すると、Google アシスタントは関連するユーザーの音声コマンドに応じてウィジェットを表示できます。組み込みインテント(BII)に応答するようにウィジェットを設定すると、Android や Android Auto などのアシスタント サーフェスにウィジェットを事前に表示できます。アシスタントによって表示されたウィジェットをランチャーに固定して、今後のエンゲージメントを促進できます。

たとえば、エクササイズ アプリのワークアウトの概要ウィジェットを構成して、GET_EXERCISE_OBSERVATION BII をトリガーするユーザーの音声コマンドを実行できます。ユーザーが「OK Google, 今週は ExampleApp で何マイル歩いた?」などのリクエストを出してこの BII をトリガーすると、アシスタントはウィジェットをプロアクティブに表示します。

ユーザー操作の複数のカテゴリをカバーする BII が数十種類あり、ほとんどの Android アプリで音声対応ウィジェットを強化できます。開始するには、App Actions を Android ウィジェットと統合するをご覧ください。

アプリのウィジェット選択ツールのエクスペリエンスを改善する

Android 12 では、スケーリングされたウィジェット プレビューとウィジェットの説明を追加できます。Android 15 では、生成されたウィジェット プレビューを使用して、アプリのウィジェット選択ツールのエクスペリエンスを改善できます。

アプリのウィジェット選択ツールのエクスペリエンスを改善するには、Android 15 以降のデバイスでは生成されたウィジェットのプレビューを、Android 12 ~ Android 14 のデバイスではスケーリングされたウィジェットのプレビュー(previewLayout を指定して)を、それ以前のバージョンでは previewImage を提供します。

生成されたウィジェット プレビューをウィジェット選択ツールに追加する

Android 15 以降のデバイスでウィジェット ピッカーに RemoteViews を提供できるようにするには、アプリでモジュール build.gradle ファイルの compileSdk 値を 35 以降に設定する必要があります。つまり、アプリは選択ツールのコンテンツを更新して、ユーザーが目にするものをより正確に表すことができます。

アプリは、AppWidgetManagersetWidgetPreviewgetWidgetPreview メソッドを使用して、最新のパーソナライズされた情報でウィジェットの外観を更新できます。

Jetpack Glance で更新されたプレビューを生成する

Glance.compose は 1 つのコンポジションを実行するため、コンポーザブルの本体では suspend 関数、フロー、または同様の非同期呼び出しは使用されません。代わりに、定数データを使用する必要があります。

次の例では、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 は Glance なしで使用できます。次の例では、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 をサポートしていない場合に、アプリが previewImage にフォールバックできます。previewLayout 属性は 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/background または android.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);