生成されたウィジェット プレビューを使用すると、ユーザーのホーム画面に表示されるウィジェットの様子を正確に反映した、動的でパーソナライズされたプレビューを作成できます。これらはプッシュ API を介して提供されます。つまり、アプリはウィジェット ホストから明示的なリクエストを受け取ることなく、ライフサイクルの任意の時点でプレビューを提供します。
アプリのウィジェット選択ツールのエクスペリエンスを改善するには、Android 15 以降のデバイスでは生成されたウィジェットのプレビューを、Android 12 ~ Android 14 のデバイスではスケーリングされたウィジェットのプレビュー(previewLayout
を指定)を、それ以前のバージョンでは previewImage
を提供します。
詳しくは、YouTube の Enrich your app with live updates and widgets をご覧ください。
生成されたウィジェットのプレビュー用にアプリをセットアップする
Android 15 以降のデバイスで生成されたウィジェットのプレビューを表示するには、まずモジュールの build.gradle
ファイルで compileSdk
の値を 35 以上に設定して、ウィジェット選択ツールに RemoteViews
を提供できるようにします。
アプリは GlanceAppWidgetManager
または AppWidgetManager
のいずれかで setWidgetPreview
を使用できます。不正使用を防ぎ、システムの健全性に関する懸念を軽減するため、setWidgetPreview
はレート制限付きの API です。デフォルトの上限は 1 時間あたり約 2 回の呼び出しです。
Jetpack Glance で更新されたプレビューを生成する
Jetpack Glance で構築されたウィジェットの場合は、次の操作を行います。
GlanceAppWidget.providePreview
関数をオーバーライドして、プレビュー用のコンポーズ可能なコンテンツを提供します。provideGlance
の場合と同様に、アプリのデータを読み込んでウィジェットのコンテンツ コンポーザブルに渡し、プレビューに正確なデータが表示されるようにします。provideGlance
とは異なり、これは再コンポーズやエフェクトのない単一のコンポジションです。GlanceAppWidgetManager.setWidgetPreviews
を呼び出して、プレビューを生成して公開します。
システムからプレビューを提供するコールバックはないため、アプリで setWidgetPreviews
を呼び出すタイミングを決定する必要があります。更新戦略は、ウィジェットのユースケースによって異なります。
- ウィジェットに静的な情報が含まれている場合や、クイック アクションである場合は、アプリの初回起動時にプレビューを設定します。
- プレビューは、アプリにデータが入力された後(ユーザーのログイン後や初期設定後など)に設定できます。
- 選択したケイデンスでプレビューを更新する定期的なタスクを設定できます。
生成されたプレビューのトラブルシューティング
一般的な問題は、プレビューを生成した後、ウィジェットのドロップサイズに対して、プレビュー画像から画像、アイコン、その他のコンポーザブルが欠落していることです。このドロップ サイズは、指定されている場合は targetCellWidth
と targetCellHeight
で定義され、指定されていない場合はアプリ ウィジェット プロバイダ情報ファイルの minWidth
と minHeight
で定義されます。
これは、Android がデフォルトで、ウィジェットの最小サイズで表示されるコンポーザブルのみをレンダリングするためです。つまり、Android はデフォルトで previewSizeMode
を SizeMode.Single
に設定します。アプリ ウィジェット プロバイダ情報 XML の android:minHeight
と android:minWidth
を使用して、描画するコンポーザブルを決定します。
これを修正するには、GlanceAppWidget
で previewSizeMode
をオーバーライドして SizeMode.Responsive
に設定し、DpSize
値のセットを指定します。これにより、プレビューのレンダリングに必要なすべてのレイアウト サイズが Android に通知され、すべての要素が正しく表示されます。
特定のフォーム ファクタ向けに最適化します。最小サイズからウィジェットのブレークポイントに沿って、1 つまたは 2 つのサイズを指定します。下位互換性のために、少なくとも 1 つのイメージを指定します。さまざまなグリッド サイズに適した最小 DP 値については、ウィジェット デザイン ガイダンスをご覧ください。
Jetpack Glance を使用せずに更新されたプレビューを生成
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>
現実的なデフォルト値またはテスト値を持つ実際のウィジェットと同じレイアウトを使用することをおすすめします。ほとんどのアプリは同じ previewLayout
と initialLayout
を使用します。正確なプレビュー レイアウトを作成するためのガイダンスについては、このページの次のセクションをご覧ください。
ユーザーのデバイスが previewLayout
をサポートしていない場合にアプリが previewImage
を使用するようにフォールバックできるように、previewLayout
属性と previewImage
属性の両方を指定することをおすすめします。previewLayout
属性は previewImage
属性よりも優先されます。
ウィジェット プレビューに関する下位互換性
Android 11(API レベル 30)以下でウィジェット選択ツールを使用してウィジェットのプレビューを表示するには、または生成されたプレビューのフォールバックとして、previewImage
属性を指定します。
ウィジェットの外観を変更する場合は、プレビュー画像を更新します。
動的アイテムを含む正確なプレビューを作成する

このセクションでは、コレクション ビュー(ListView
、GridView
、StackView
を使用するウィジェット)を含むウィジェットのウィジェット プレビューに複数のアイテムを表示する場合の推奨アプローチについて説明します。これは、生成されたウィジェットのプレビューには適用されません。
ウィジェットがこれらのビューのいずれかを使用している場合、実際のウィジェット レイアウトを直接提供することでスケーラブルなプレビューを作成すると、ウィジェット プレビューにアイテムが表示されないときにエクスペリエンスが低下します。これは、コレクション ビューのデータが実行時に動的に設定されるためで、図 1 に示す画像と似たような表示になります。
コレクション ビューを含むウィジェットのプレビューをウィジェット ピッカーで正しく表示するには、プレビュー専用の個別のレイアウト ファイルを維持することをおすすめします。この別のレイアウト ファイルには、次のものを含める必要があります。
- 実際のウィジェットのレイアウト。
- 偽のアイテムを含むプレースホルダ コレクション ビュー。たとえば、複数の偽のリスト項目を含むプレースホルダ
LinearLayout
を指定することで、ListView
を模倣できます。
ListView
の例を示すため、別のレイアウト ファイルから始めます。
// res/layout/widget_preview.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/widget_background"
android:orientation="vertical">
// Include the actual widget layout that contains ListView.
<include
layout="@layout/widget_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
// The number of fake items you include depends on the values you provide
// for minHeight or targetCellHeight in the AppWidgetProviderInfo
// definition.
<TextView android:text="@string/fake_item1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="?attr/appWidgetInternalPadding" />
<TextView android:text="@string/fake_item2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="?attr/appWidgetInternalPadding" />
</LinearLayout>
AppWidgetProviderInfo
メタデータの previewLayout
属性を指定するときに、プレビュー レイアウト ファイルを指定します。initialLayout
属性の実際のウィジェット レイアウトは指定し、実行時に RemoteViews
を構築するときに実際のウィジェット レイアウトを使用します。
<appwidget-provider
previewLayout="@layout/widget_previe"
initialLayout="@layout/widget_view" />
複雑なリストアイテム
前のセクションの例では、リストアイテムが TextView
オブジェクトであるため、偽のリストアイテムが提供されます。アイテムが複雑なレイアウトの場合、偽のアイテムを提供するのは複雑になる可能性があります。
widget_list_item.xml
で定義され、2 つの TextView
オブジェクトで構成されるリストアイテムについて考えてみましょう。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fake_title" />
<TextView android:id="@id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fake_content" />
</LinearLayout>
偽のリスト項目を提供するには、レイアウトを複数回含めることができますが、これにより各リスト項目が同一になります。一意のリスト項目を提供するには、次の手順を行います。
テキスト値の属性のセットを作成します。
<resources> <attr name="widgetTitle" format="string" /> <attr name="widgetContent" format="string" /> </resources>
次の属性を使用してテキストを設定します。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="?widgetTitle" /> <TextView android:id="@id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="?widgetContent" /> </LinearLayout>
プレビューに必要な数のスタイルを作成します。各スタイルの値を再定義します。
<resources> <style name="Theme.Widget.ListItem"> <item name="widgetTitle"></item> <item name="widgetContent"></item> </style> <style name="Theme.Widget.ListItem.Preview1"> <item name="widgetTitle">Fake Title 1</item> <item name="widgetContent">Fake content 1</item> </style> <style name="Theme.Widget.ListItem.Preview2"> <item name="widgetTitle">Fake title 2</item> <item name="widgetContent">Fake content 2</item> </style> </resources>
プレビュー レイアウトのフェイク アイテムにスタイルを適用します。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" ...> <include layout="@layout/widget_view" ... /> <include layout="@layout/widget_list_item" android:theme="@style/Theme.Widget.ListItem.Preview1" /> <include layout="@layout/widget_list_item" android:theme="@style/Theme.Widget.ListItem.Preview2" /> </LinearLayout>