Vorschauen zur Widget-Auswahl hinzufügen

Um die Auswahl von Widgets in Ihrer App zu verbessern, sollten Sie auf Geräten mit Android 15 und höher eine generierte Widget-Vorschau, auf Geräten mit Android 12 bis Android 14 eine skalierte Widget-Vorschau (durch Angabe eines previewLayout) und für frühere Versionen ein previewImage bereitstellen.

Mit generierten Widget-Vorschauen können Sie dynamische, personalisierte Vorschauen für Ihre Widgets erstellen, die genau widerspiegeln, wie sie auf dem Startbildschirm eines Nutzers angezeigt werden. Unter Android 15 und höher werden sie über eine Push-API bereitgestellt. Das bedeutet, dass Ihre App die Vorschau zu einem beliebigen Zeitpunkt während ihres Lebenszyklus bereitstellt, ohne eine explizite Anfrage vom Widget-Host zu erhalten.

Weitere Informationen finden Sie auf YouTube unter Enrich your app with live updates and widgets.

Generierte Vorschauen hinzufügen

Wenn Sie generierte Widget-Vorschaubilder auf einem Gerät mit Android 15 oder höher anzeigen möchten, müssen Sie zuerst den compileSdk-Wert in der Moduldatei build.gradle auf 35 oder höher festlegen, damit Sie dem Widget-Picker RemoteViews zur Verfügung stellen können.

Apps können setWidgetPreview in AppWidgetManager verwenden. Um Missbrauch zu verhindern und Bedenken hinsichtlich der Systemintegrität auszuräumen, ist setWidgetPreview eine API mit Ratenbegrenzung. Das Standardlimit liegt bei etwa zwei Anrufen pro Stunde.

Es gibt keinen Callback vom System, um Vorschauen bereitzustellen. Ihre App muss also entscheiden, wann setWidgetPreviews aufgerufen werden soll. Die Aktualisierungsstrategie hängt vom Anwendungsfall Ihres Widgets ab:

  • Wenn das Widget statische Informationen enthält oder eine Schnellaktion ist, legen Sie die Vorschau beim ersten Starten der App fest.
  • Sie können die Vorschau festlegen, sobald Ihre App Daten hat, z. B. nach der Anmeldung eines Nutzers oder der Ersteinrichtung.
  • Sie können einen regelmäßigen Task einrichten, um die Vorschauen in einem bestimmten Rhythmus zu aktualisieren.

Im folgenden Beispiel wird eine XML-Ressource für das Widget-Layout geladen und als Vorschau festgelegt. Für die Anzeige von setWidgetPreview als Methode in diesem Snippet ist die Build-Einstellung „compileSdk“ 35 oder höher erforderlich.

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

Skalierbare Widget-Vorschauen hinzufügen

Ab Android 12 ist die im Widget-Picker angezeigte Widget-Vorschau skalierbar. Sie stellen es als XML-Layout bereit, das auf die Standardgröße des Widgets festgelegt ist. Bisher war die Widget-Vorschau eine statische Drawable-Ressource. In einigen Fällen wurde daher nicht genau angezeigt, wie Widgets aussehen, wenn sie dem Startbildschirm hinzugefügt werden.

Wenn Sie skalierbare Widget-Vorschauen implementieren möchten, verwenden Sie das Attribut previewLayout des Elements appwidget-provider, um stattdessen ein XML-Layout anzugeben:

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

Wir empfehlen, dass Sie dasselbe Layout wie für das tatsächliche Widget verwenden und realistische Standard- oder Testwerte angeben. Die meisten Apps verwenden dieselben previewLayout und initialLayout. Genaue Vorschauen mit dynamischen Elementen erstellen

Wir empfehlen, sowohl das Attribut previewLayout als auch das Attribut previewImage anzugeben, damit Ihre App auf previewImage zurückgreifen kann, wenn das Gerät des Nutzers previewLayout nicht unterstützt. Das Attribut previewLayout hat Vorrang vor dem Attribut previewImage.

Statische Widget-Vorschauen für Abwärtskompatibilität hinzufügen

Wenn Sie möchten, dass in der Widget-Auswahl unter Android 11 (API‑Level 30) oder niedriger Vorschauen Ihres Widgets angezeigt werden, oder als Fallback für skalierbare Vorschauen, geben Sie das Attribut previewImage an.

Wenn Sie das Aussehen des Widgets ändern, aktualisieren Sie das Vorschaubild.

Dieses Attribut wird auch als Fallback für generierte Vorschauen verwendet, wenn Sie keine mit setWidgetPreview festgelegt haben.

Genaue Vorschauen mit dynamischen Elementen erstellen

Abbildung 1 : Eine Widget-Vorschau ohne Listenelemente.

In diesem Abschnitt wird die empfohlene Vorgehensweise zum Anzeigen mehrerer Elemente in einer Widget-Vorschau für ein Widget mit einer Sammlungsansicht beschrieben. Das ist ein Widget, das ListView, GridView oder StackView verwendet. Das gilt für skalierbare Widget-Vorschauen, nicht für generierte Vorschauen.

Wenn Ihr Widget eine dieser Ansichten verwendet, kann es zu Problemen kommen, wenn Sie eine skalierbare Vorschau erstellen, indem Sie das tatsächliche Widget-Layout direkt in previewLayout angeben. Das liegt daran, dass in der Widget-Vorschau dann möglicherweise keine Elemente angezeigt werden. Das liegt daran, dass die Daten für die Sammlung dynamisch zur Laufzeit festgelegt werden. Sie sehen ähnlich aus wie das Bild in Abbildung 1.

Damit Vorschauen von Widgets mit Sammlungsansichten in der Widget-Auswahl richtig angezeigt werden, empfehlen wir, eine separate Layoutdatei nur für die Vorschau zu verwenden. Diese separate Layoutdatei sollte Folgendes enthalten:

  • Das tatsächliche Widget-Layout.
  • Eine Platzhalter-Sammlungsansicht mit gefälschten Elementen. Sie können beispielsweise ein ListView simulieren, indem Sie einen Platzhalter LinearLayout mit mehreren gefälschten Listenelementen angeben.

Hier ist ein Beispiel für eine ListView, das mit einer separaten Layoutdatei beginnt:

// 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>

Geben Sie die Datei für das Vorschau-Layout an, wenn Sie das Attribut previewLayout der AppWidgetProviderInfo-Metadaten angeben. Sie geben das tatsächliche Widget-Layout weiterhin für das Attribut initialLayout an und verwenden es, wenn Sie zur Laufzeit ein RemoteViews erstellen.

<appwidget-provider
    previewLayout="@layout/widget_preview"
    initialLayout="@layout/widget_view" />

Komplexe Listenelemente

Im Beispiel im vorherigen Abschnitt werden gefälschte Listenelemente verwendet, da die Listenelemente TextView-Objekte sind. Es kann schwieriger sein, gefälschte Artikel zu erstellen, wenn die Artikel komplexe Layouts haben.

Angenommen, ein Listenelement wird in widget_list_item.xml definiert und besteht aus zwei TextView-Objekten:

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

Wenn Sie gefälschte Listenelemente angeben möchten, können Sie das Layout mehrmals einfügen. Dadurch sind jedoch alle Listenelemente identisch. So stellen Sie eindeutige Listenelemente bereit:

  1. Erstellen Sie eine Reihe von Attributen für die Textwerte:

    <resources>
        <attr name="widgetTitle" format="string" />
        <attr name="widgetContent" format="string" />
    </resources>
    
  2. Verwenden Sie diese Attribute, um den Text festzulegen:

    <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>
    
  3. Erstellen Sie so viele Stile, wie für die Vorschau erforderlich sind. Definieren Sie die Werte in jedem Stil neu:

    <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>
    
  4. Wenden Sie die Stile auf die Platzhalterelemente im Vorschaulayout an:

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