Einfaches Widget erstellen

Compose ausprobieren
Jetpack Compose ist das empfohlene UI-Toolkit für Android. Informationen zum Erstellen von Widgets mit APIs im Compose-Stil.

App-Widgets sind Miniaturansichten von Apps, die Sie in andere Apps wie den Startbildschirm einbetten und regelmäßig aktualisieren lassen können. Diese Ansichten werden auf der Benutzeroberfläche als Widgets bezeichnet. Sie können ein Widget mit einem App-Widget-Provider (oder Widget-Provider) veröffentlichen. Eine App-Komponente, die andere Widgets enthält, wird als App-Widget-Host (oder Widget-Host) bezeichnet. Abbildung 1 zeigt ein Beispiel für ein Musik-Widget:

Beispiel für ein Musik-Widget
Abbildung 1: Beispiel für ein Musik-Widget

In diesem Dokument wird beschrieben, wie Sie ein Widget mithilfe eines Widget-Anbieters veröffentlichen. Weitere Informationen zum Erstellen eines eigenen AppWidgetHost zum Hosten von App-Widgets finden Sie unter Widget-Host erstellen.

Informationen zum Design von Widgets finden Sie unter App-Widgets – Übersicht.

Widget-Komponenten

Zum Erstellen eines Widgets benötigen Sie die folgenden grundlegenden Komponenten:

AppWidgetProviderInfo-Objekt
Beschreibt die Metadaten für ein Widget, z. B. das Layout, die Aktualisierungshäufigkeit und die AppWidgetProvider-Klasse des Widgets. AppWidgetProviderInfo wird in XML definiert, wie in diesem Dokument beschrieben.
AppWidgetProvider-Klasse
Definiert die grundlegenden Methoden, mit denen Sie programmatisch mit dem Widget interagieren können. Darüber erhalten Sie Broadcasts, wenn das Widget aktualisiert, aktiviert, deaktiviert oder gelöscht wird. Sie deklarieren AppWidgetProvider im Manifest und implementieren es dann, wie in diesem Dokument beschrieben.
Layout ansehen
Defines the initial layout for the widget. Das Layout wird in XML definiert, wie in diesem Dokument beschrieben.

Abbildung 2 zeigt, wie diese Komponenten in den allgemeinen Ablauf der Verarbeitung von App-Widgets passen.

Verarbeitungsablauf für App-Widgets
Abbildung 2. Ablauf der Verarbeitung von App-Widgets.

Wenn für Ihr Widget eine Nutzerkonfiguration erforderlich ist, implementieren Sie die Aktivität zur Konfiguration von App-Widgets. Mit dieser Aktivität können Nutzer Widget-Einstellungen ändern, z. B. die Zeitzone für ein Uhr-Widget.

Außerdem empfehlen wir die folgenden Verbesserungen: Flexible Widget-Layouts, Sonstige Verbesserungen, Erweiterte Widgets, Sammlungs-Widgets und Erstellen eines Widget-Hosts.

AppWidgetProviderInfo-XML deklarieren

Das AppWidgetProviderInfo-Objekt definiert die wesentlichen Eigenschaften eines Widgets. Definieren Sie das AppWidgetProviderInfo-Objekt in einer XML-Ressourcendatei mit einem einzelnen <appwidget-provider>-Element und speichern Sie es im res/xml/-Ordner des Projekts.

Dies wird im folgenden Beispiel veranschaulicht:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="40dp"
    android:minHeight="40dp"
    android:targetCellWidth="1"
    android:targetCellHeight="1"
    android:maxResizeWidth="250dp"
    android:maxResizeHeight="120dp"
    android:updatePeriodMillis="86400000"
    android:description="@string/example_appwidget_description"
    android:previewLayout="@layout/example_appwidget_preview"
    android:initialLayout="@layout/example_loading_appwidget"
    android:configure="com.example.android.ExampleAppWidgetConfigurationActivity"
    android:resizeMode="horizontal|vertical"
    android:widgetCategory="home_screen"
    android:widgetFeatures="reconfigurable|configuration_optional">
</appwidget-provider>

Attribute für die Widget-Größe

Auf dem Standard-Startbildschirm werden Widgets in ihrem Fenster basierend auf einem Raster von Zellen mit definierter Höhe und Breite positioniert. Auf den meisten Startbildschirmen können Widgets nur Größen annehmen, die ganzzahlige Vielfache der Rasterzellen sind, z. B. zwei Zellen horizontal mal drei Zellen vertikal.

Mit den Attributen für die Widget-Größe können Sie eine Standardgröße für Ihr Widget festlegen und Unter- und Obergrenzen für die Größe des Widgets angeben. In diesem Zusammenhang ist die Standardgröße eines Widgets die Größe, die das Widget annimmt, wenn es zum ersten Mal dem Startbildschirm hinzugefügt wird.

In der folgenden Tabelle werden die <appwidget-provider>-Attribute für die Widget-Größe beschrieben:

Attribute und Beschreibung
targetCellWidth und targetCellHeight (Android 12), minWidth und minHeight
  • Ab Android 12 geben die Attribute targetCellWidth und targetCellHeight die Standardgröße des Widgets in Bezug auf Rasterzellen an. Diese Attribute werden in Android 11 und niedriger ignoriert und können ignoriert werden, wenn der Startbildschirm kein rasterbasiertes Layout unterstützt.
  • Die Attribute minWidth und minHeight geben die Standardgröße des Widgets in dp an. Wenn die Werte für die Mindestbreite oder ‑höhe eines Widgets nicht mit den Abmessungen der Zellen übereinstimmen, werden die Werte auf die nächste Zellengröße aufgerundet.
Wir empfehlen, beide Attributgruppen anzugeben: targetCellWidth und targetCellHeight sowie minWidth und minHeight. So kann Ihre App auf minWidth und minHeight zurückgreifen, wenn das Gerät des Nutzers targetCellWidth und targetCellHeight nicht unterstützt. Falls unterstützt, haben die Attribute targetCellWidth und targetCellHeight Vorrang vor den Attributen minWidth und minHeight.
minResizeWidth und minResizeHeight Geben Sie die absolute Mindestgröße des Widgets an. Diese Werte geben die Größe an, unter der das Widget nicht mehr lesbar oder anderweitig nicht mehr nutzbar ist. Mit diesen Attributen kann der Nutzer die Größe des Widgets auf eine Größe ändern, die kleiner als die Standardgröße des Widgets ist. Das Attribut minResizeWidth wird ignoriert, wenn es größer als minWidth ist oder wenn die horizontale Größenanpassung nicht aktiviert ist. Weitere Informationen finden Sie unter resizeMode. Ebenso wird das Attribut minResizeHeight ignoriert, wenn es größer als minHeight ist oder wenn die vertikale Größenanpassung nicht aktiviert ist.
maxResizeWidth und maxResizeHeight Geben Sie die empfohlene maximale Größe des Widgets an. Wenn die Werte kein Vielfaches der Rasterzellendimensionen sind, werden sie auf die nächste Zellengröße aufgerundet. Das Attribut maxResizeWidth wird ignoriert, wenn es kleiner als minWidth ist oder wenn die horizontale Größenanpassung nicht aktiviert ist. Weitere Informationen finden Sie unter resizeMode. Ebenso wird das Attribut maxResizeHeight ignoriert, wenn es größer als minHeight ist oder wenn die vertikale Größenanpassung nicht aktiviert ist. Eingeführt in Android 12.
resizeMode Gibt die Regeln an, nach denen die Größe eines Widgets geändert werden kann. Mit diesem Attribut können Sie festlegen, dass Startbildschirm-Widgets horizontal, vertikal oder auf beiden Achsen in der Größe angepasst werden können. Nutzer berühren und halten ein Widget, um die Ziehpunkte zum Anpassen der Größe aufzurufen. Anschließend ziehen sie die horizontalen oder vertikalen Ziehpunkte, um die Größe des Widgets im Layoutraster zu ändern. Mögliche Werte für das Attribut resizeMode sind horizontal, vertical und none. Wenn Sie ein Widget als horizontal und vertikal anpassbar deklarieren möchten, verwenden Sie horizontal|vertical.

Beispiel

Zur Veranschaulichung der Auswirkungen der Attribute in der vorherigen Tabelle auf die Größe von Widgets nehmen wir die folgenden Spezifikationen an:

  • Eine Rasterzelle ist 30 dp breit und 50 dp hoch.
  • Die folgende Attributspezifikation ist verfügbar:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="80dp"
    android:minHeight="80dp"
    android:targetCellWidth="2"
    android:targetCellHeight="2"
    android:minResizeWidth="40dp"
    android:minResizeHeight="40dp"
    android:maxResizeWidth="120dp"
    android:maxResizeHeight="120dp"
    android:resizeMode="horizontal|vertical" />

Ab Android 12:

Verwenden Sie die Attribute targetCellWidth und targetCellHeight als Standardgröße des Widgets.

Die Standardgröße des Widgets ist 2 × 2. Die Größe des Widgets kann auf 2 × 1 oder bis zu 4 × 3 geändert werden.

Android 11 und niedriger:

Mit den Attributen minWidth und minHeight können Sie die Standardgröße des Widgets berechnen.

Die Standardbreite ist Math.ceil(80 / 30) = 3.

Die Standardhöhe ist Math.ceil(80 / 50) = 2.

Die Standardgröße des Widgets ist 3 × 2. Das Widget kann auf 2 × 1 oder auf den Vollbildmodus verkleinert bzw. vergrößert werden.

Zusätzliche Widget-Attribute

In der folgenden Tabelle werden die <appwidget-provider>-Attribute beschrieben, die sich auf andere Aspekte als die Widget-Größe beziehen.

Attribute und Beschreibung
updatePeriodMillis Legt fest, wie oft das Widget-Framework ein Update von AppWidgetProvider anfordert, indem die Callback-Methode onUpdate() aufgerufen wird. Es ist nicht garantiert, dass die tatsächliche Aktualisierung genau zu diesem Zeitpunkt erfolgt. Wir empfehlen, die Aktualisierung so selten wie möglich durchzuführen – nicht öfter als einmal pro Stunde –, um den Akku zu schonen. Eine vollständige Liste der Überlegungen zur Auswahl eines geeigneten Aktualisierungszeitraums finden Sie unter Optimierungen für die Aktualisierung von Widget-Inhalten.
initialLayout Verweist auf die Layoutressource, die das Widget-Layout definiert.
configure Definiert die Aktivität, die gestartet wird, wenn der Nutzer das Widget hinzufügt. So kann er die Widget-Attribute konfigurieren. Weitere Informationen finden Sie unter Nutzern die Konfiguration von Widgets ermöglichen. Ab Android 12 kann Ihre App die Erstkonfiguration überspringen. Weitere Informationen finden Sie unter Standardkonfiguration des Widgets verwenden.
description Gibt die Beschreibung für die Widget-Auswahl an, die für Ihr Widget angezeigt werden soll. Eingeführt in Android 12.
previewLayout (Android 12) und previewImage (Android 11 und niedriger)
  • Ab Android 12 gibt das Attribut previewLayout eine skalierbare Vorschau an, die Sie als XML-Layout in der Standardgröße des Widgets bereitstellen. Im Idealfall ist das als dieses Attribut angegebene Layout-XML dasselbe Layout-XML wie das tatsächliche Widget mit realistischen Standardwerten.
  • In Android 11 oder niedriger gibt das Attribut previewImage eine Vorschau des konfigurierten Widgets an, die dem Nutzer angezeigt wird, wenn er das App-Widget auswählt. Wenn nicht angegeben, sieht der Nutzer stattdessen das Launcher-Symbol Ihrer App. Dieses Feld entspricht dem Attribut android:previewImage im Element <receiver> in der Datei AndroidManifest.xml.
Hinweis:Wir empfehlen, sowohl das Attribut previewImage als auch das Attribut previewLayout anzugeben, damit Ihre App auf previewImage zurückgreifen kann, wenn das Gerät des Nutzers previewLayout nicht unterstützt. Weitere Informationen finden Sie unter Abwärtskompatibilität mit skalierbaren Widget-Vorschaubildern.
autoAdvanceViewId Gibt die Ansichts-ID der untergeordneten Ansicht des Widgets an, die vom Host des Widgets automatisch weitergeschaltet wird.
widgetCategory Gibt an, ob Ihr Widget auf dem Startbildschirm (home_screen), dem Sperrbildschirm (keyguard) oder beiden angezeigt werden kann. Bei Android 5.0 und höher ist nur home_screen gültig.
widgetFeatures Gibt die vom Widget unterstützten Funktionen an. Wenn Ihr Widget beispielsweise seine Standardkonfiguration verwenden soll, wenn ein Nutzer es hinzufügt, geben Sie sowohl das Flag configuration_optional als auch das Flag reconfigurable an. Dadurch wird das Starten der Konfigurationsaktivität umgangen, nachdem ein Nutzer das Widget hinzugefügt hat. Der Nutzer kann das Widget später neu konfigurieren.

AppWidgetProvider-Klasse zum Verarbeiten von Widget-Broadcasts verwenden

Die Klasse AppWidgetProvider verarbeitet Widget-Broadcasts und aktualisiert das Widget als Reaktion auf Widget-Lebenszyklusereignisse. In den folgenden Abschnitten wird beschrieben, wie Sie AppWidgetProvider im Manifest deklarieren und dann implementieren.

Widget im Manifest deklarieren

Deklarieren Sie zuerst die Klasse AppWidgetProvider in der Datei AndroidManifest.xml Ihrer App, wie im folgenden Beispiel gezeigt:

<receiver android:name="ExampleAppWidgetProvider"
                 android:exported="false">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data android:name="android.appwidget.provider"
               android:resource="@xml/example_appwidget_info" />
</receiver>

Für das <receiver>-Element ist das Attribut android:name erforderlich, das die vom Widget verwendete AppWidgetProvider angibt. Die Komponente darf nicht exportiert werden, es sei denn, ein separater Prozess muss eine Broadcast-Nachricht an Ihr AppWidgetProvider senden. Das ist in der Regel nicht der Fall.

Das <intent-filter>-Element muss ein <action>-Element mit dem Attribut android:name enthalten. Dieses Attribut gibt an, dass das AppWidgetProvider die ACTION_APPWIDGET_UPDATE-Broadcast akzeptiert. Dies ist der einzige Broadcast, den Sie explizit deklarieren müssen. Der AppWidgetManager sendet alle anderen Widget-Broadcasts automatisch an den AppWidgetProvider, falls erforderlich.

Das <meta-data>-Element gibt die AppWidgetProviderInfo-Ressource an und erfordert die folgenden Attribute:

  • android:name: Gibt den Metadatennamen an. Verwenden Sie android.appwidget.provider, um die Daten als AppWidgetProviderInfo-Deskriptor zu kennzeichnen.
  • android:resource: Gibt den Speicherort der AppWidgetProviderInfo-Ressource an.

AppWidgetProvider-Klasse implementieren

Die Klasse AppWidgetProvider erweitert BroadcastReceiver als Convenience-Klasse für die Verarbeitung von Widget-Broadcasts. Es empfängt nur die Ereignis-Broadcasts, die für das Widget relevant sind, z. B. wenn das Widget aktualisiert, gelöscht, aktiviert oder deaktiviert wird. Wenn diese Broadcast-Ereignisse eintreten, werden die folgenden AppWidgetProvider-Methoden aufgerufen:

onUpdate()
Diese Funktion wird aufgerufen, um das Widget in Intervallen zu aktualisieren, die durch das Attribut updatePeriodMillis im AppWidgetProviderInfo definiert werden. Weitere Informationen finden Sie auf dieser Seite in der Tabelle mit zusätzlichen Widget-Attributen.
Diese Methode wird auch aufgerufen, wenn der Nutzer das Widget hinzufügt. Sie führt die erforderliche Einrichtung durch, z. B. das Definieren von Ereignishandlern für View-Objekte oder das Starten von Jobs zum Laden von Daten, die im Widget angezeigt werden sollen. Wenn Sie jedoch eine Konfigurationsaktivität ohne das Flag configuration_optional deklarieren, wird diese Methode nicht aufgerufen, wenn der Nutzer das Widget hinzufügt. Sie wird jedoch bei den nachfolgenden Aktualisierungen aufgerufen. Es liegt in der Verantwortung der Konfigurationsaktivität, das erste Update durchzuführen, wenn die Konfiguration abgeschlossen ist. Weitere Informationen finden Sie unter Nutzern ermöglichen, App-Widgets zu konfigurieren.
Der wichtigste Callback ist onUpdate(). Weitere Informationen finden Sie auf dieser Seite unter Ereignisse mit der Klasse onUpdate() verarbeiten.
onAppWidgetOptionsChanged()

Diese Methode wird aufgerufen, wenn das Widget zum ersten Mal platziert wird und jedes Mal, wenn die Größe des Widgets geändert wird. Mit diesem Callback können Sie Inhalte basierend auf den Größenbereichen des Widgets ein- oder ausblenden. Die Größenbereiche und ab Android 12 die Liste der möglichen Größen, die eine Widget-Instanz annehmen kann, erhalten Sie durch Aufrufen von getAppWidgetOptions(). Diese Funktion gibt ein Bundle zurück, das Folgendes enthält:

onDeleted(Context, int[])

Diese Methode wird jedes Mal aufgerufen, wenn ein Widget vom Widget-Host gelöscht wird.

onEnabled(Context)

Diese Methode wird aufgerufen, wenn eine Instanz des Widgets zum ersten Mal erstellt wird. Wenn der Nutzer beispielsweise zwei Instanzen Ihres Widgets hinzufügt, wird diese Funktion nur beim ersten Mal aufgerufen. Wenn Sie eine neue Datenbank öffnen oder eine andere Einrichtung vornehmen müssen, die nur einmal für alle Widget-Instanzen erforderlich ist, ist dies ein guter Ort dafür.

onDisabled(Context)

Diese Methode wird aufgerufen, wenn die letzte Instanz Ihres Widgets vom Widget-Host gelöscht wird. Hier können Sie alle Arbeiten in onEnabled(Context) bereinigen, z. B. eine temporäre Datenbank löschen.

onReceive(Context, Intent)

Diese Methode wird für jede Übertragung und vor jeder der oben genannten Callback-Methoden aufgerufen. Normalerweise müssen Sie diese Methode nicht implementieren, da in der Standardimplementierung von AppWidgetProvider alle Widget-Broadcasts gefiltert und die vorherigen Methoden entsprechend aufgerufen werden.

Sie müssen Ihre AppWidgetProvider-Klassenimplementierung als Broadcast-Receiver mithilfe des <receiver>-Elements im AndroidManifest deklarieren. Weitere Informationen finden Sie auf dieser Seite unter Widget im Manifest deklarieren.

Ereignisse mit der Klasse „onUpdate()“ verarbeiten

Der wichtigste AppWidgetProvider-Callback ist onUpdate(), da er aufgerufen wird, wenn jedem Widget ein Host hinzugefügt wird, es sei denn, Sie verwenden eine Konfigurationsaktivität ohne das Flag configuration_optional. Wenn Ihr Widget Nutzerinteraktionsereignisse akzeptiert, registrieren Sie die Event-Handler in diesem Callback. Wenn Ihr Widget keine temporären Dateien oder Datenbanken erstellt oder andere Aufgaben ausführt, die eine Bereinigung erfordern, ist onUpdate() möglicherweise die einzige Callback-Methode, die Sie definieren müssen.

Wenn Sie beispielsweise ein Widget mit einer Schaltfläche erstellen möchten, die beim Tippen eine Aktivität startet, können Sie die folgende Implementierung von AppWidgetProvider verwenden:

Kotlin

class ExampleAppWidgetProvider : AppWidgetProvider() {

    override fun onUpdate(
            context: Context,
            appWidgetManager: AppWidgetManager,
            appWidgetIds: IntArray
    ) {
        // Perform this loop procedure for each widget that belongs to this
        // provider.
        appWidgetIds.forEach { appWidgetId ->
            // Create an Intent to launch ExampleActivity.
            val pendingIntent: PendingIntent = PendingIntent.getActivity(
                    /* context = */ context,
                    /* requestCode = */  0,
                    /* intent = */ Intent(context, ExampleActivity::class.java),
                    /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )

            // Get the layout for the widget and attach an onClick listener to
            // the button.
            val views: RemoteViews = RemoteViews(
                    context.packageName,
                    R.layout.appwidget_provider_layout
            ).apply {
                setOnClickPendingIntent(R.id.button, pendingIntent)
            }

            // Tell the AppWidgetManager to perform an update on the current
            // widget.
            appWidgetManager.updateAppWidget(appWidgetId, views)
        }
    }
}

Java

public class ExampleAppWidgetProvider extends AppWidgetProvider {

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // Perform this loop procedure for each widget that belongs to this
        // provider.
        for (int i=0; i < appWidgetIds.length; i++) {
            int appWidgetId = appWidgetIds[i];
            // Create an Intent to launch ExampleActivity
            Intent intent = new Intent(context, ExampleActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(
                /* context = */ context,
                /* requestCode = */ 0,
                /* intent = */ intent,
                /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
            );

            // Get the layout for the widget and attach an onClick listener to
            // the button.
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget_layout);
            views.setOnClickPendingIntent(R.id.button, pendingIntent);

            // Tell the AppWidgetManager to perform an update on the current app
            // widget.
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    }
}

Diese AppWidgetProvider definiert nur die onUpdate()-Methode. Mit ihr wird ein PendingIntent erstellt, das ein Activity startet und es mit setOnClickPendingIntent(int, PendingIntent) an die Schaltfläche des Widgets anhängt. Sie enthält eine Schleife, die jeden Eintrag in appWidgetIds durchläuft. appWidgetIds ist ein Array von IDs, die jedes von diesem Anbieter erstellte Widget identifizieren. Wenn der Nutzer mehrere Instanzen des Widgets erstellt, werden alle gleichzeitig aktualisiert. Es wird jedoch nur ein updatePeriodMillis-Zeitplan für alle Instanzen des Widgets verwaltet. Wenn der Aktualisierungszeitplan beispielsweise alle zwei Stunden festgelegt ist und eine zweite Instanz des Widgets eine Stunde nach der ersten hinzugefügt wird, werden beide im Zeitraum der ersten Instanz aktualisiert. Der zweite Aktualisierungszeitraum wird ignoriert. Beide werden alle zwei Stunden aktualisiert, nicht jede Stunde.

Weitere Informationen finden Sie in der Beispielklasse ExampleAppWidgetProvider.java.

Broadcast-Intents für Widgets empfangen

AppWidgetProvider ist eine Hilfsklasse. Wenn Sie die Widget-Broadcasts direkt empfangen möchten, können Sie Ihre eigene BroadcastReceiver implementieren oder den onReceive(Context,Intent)-Callback überschreiben. Die folgenden Intents sind wichtig:

Widget-Layout erstellen

Sie müssen ein anfängliches Layout für Ihr Widget in XML definieren und im Verzeichnis res/layout/ des Projekts speichern. Weitere Informationen finden Sie in den Designrichtlinien.

Wenn Sie mit Layouts vertraut sind, ist das Erstellen des Widget-Layouts ganz einfach. Widget-Layouts basieren jedoch auf RemoteViews, das nicht alle Arten von Layouts oder Ansichts-Widgets unterstützt. Sie können keine benutzerdefinierten Ansichten oder Unterklassen der von RemoteViews unterstützten Ansichten verwenden.

RemoteViews unterstützt auch ViewStub, eine unsichtbare View mit der Größe null, mit der Sie Layoutressourcen zur Laufzeit verzögert aufblähen können.

Unterstützung für zustandsorientiertes Verhalten

In Android 12 wird die Unterstützung für zustandsbehaftetes Verhalten mit den folgenden vorhandenen Komponenten hinzugefügt:

Das Widget ist weiterhin zustandslos. Ihre App muss den Status speichern und sich für Statusänderungsereignisse registrieren.

Beispiel für ein Einkaufslisten-Widget mit zustandsorientiertem Verhalten
Abbildung 3: Beispiel für zustandsorientiertes Verhalten.

Im folgenden Codebeispiel sehen Sie, wie Sie diese Komponenten implementieren.

Kotlin

// Check the view.
remoteView.setCompoundButtonChecked(R.id.my_checkbox, true)

// Check a radio group.
remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2)

// Listen for check changes. The intent has an extra with the key
// EXTRA_CHECKED that specifies the current checked state of the view.
remoteView.setOnCheckedChangeResponse(
        R.id.my_checkbox,
        RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent)
)

Java

// Check the view.
remoteView.setCompoundButtonChecked(R.id.my_checkbox, true);

// Check a radio group.
remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2);

// Listen for check changes. The intent has an extra with the key
// EXTRA_CHECKED that specifies the current checked state of the view.
remoteView.setOnCheckedChangeResponse(
    R.id.my_checkbox,
    RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent));

Stellen Sie zwei Layouts bereit: eines für Geräte mit Android 12 oder höher in res/layout-v31 und das andere für Geräte mit Android 11 oder niedriger im Standardordner res/layout.

Abgerundete Ecken implementieren

In Android 12 werden die folgenden Systemparameter eingeführt, um die Radien der abgerundeten Ecken Ihres Widgets festzulegen:

  • system_app_widget_background_radius: Der Eckenradius des Widget-Hintergrunds, der nie größer als 28 dp ist.

  • Der innere Radius, der aus dem äußeren Radius und dem Padding berechnet werden kann. Hier ein Beispiel-Snippet:

    /**
     * Applies corner radius for views that are visually positioned [widgetPadding]dp inside of the
     * widget background.
     */
    @Composable
    fun GlanceModifier.appWidgetInnerCornerRadius(widgetPadding: Dp): GlanceModifier {
    
        if (Build.VERSION.SDK_INT < 31) {
            return this
        }
    
        val resources = LocalContext.current.resources
        // get dimension in float (without rounding).
        val px = resources.getDimension(android.R.dimen.system_app_widget_background_radius)
        val widgetBackgroundRadiusDpValue = px / resources.displayMetrics.density
        if (widgetBackgroundRadiusDpValue < widgetPadding.value) {
            return this
        }
        return this.cornerRadius(Dp(widgetBackgroundRadiusDpValue - widgetPadding.value))
    }

Verwenden Sie die folgende Formel, um einen geeigneten Radius für den inneren Inhalt Ihres Widgets zu berechnen: systemRadiusValue - widgetPadding

Bei Widgets, bei denen Inhalte auf nicht rechteckige Formen zugeschnitten werden, sollte @android:id/background als Ansichts-ID der Hintergrundansicht verwendet werden, für die android:clipToOutline auf true festgelegt ist.

Wichtige Hinweise zu abgerundeten Ecken

  • Drittanbieter-Launcher und Gerätehersteller können den Parameter system_app_widget_background_radius auf einen Wert unter 28 dp festlegen.
  • Wenn Ihr Widget @android:id/background nicht verwendet oder keinen Hintergrund definiert, der seine Inhalte basierend auf dem Umriss zuschneidet (mit android:clipToOutline auf true gesetzt), erkennt der Launcher den Hintergrund automatisch und schneidet das Widget mit einem Rechteck mit abgerundeten Ecken zu, das auf den Systemradius eingestellt ist.

  • Nicht rechteckige Formen müssen in ihrem abgerundeten rechteckigen Container enthalten sein, damit sie nicht abgeschnitten werden.

  • Ab Android 16 lautet der AOSP-Systemwert für system_app_widget_background_radius 24dp. Launcher und Gerätehersteller können das Widget auf system_app_widget_background_radius beschränken.

  • Der innere Inhalt eines Widgets muss ausreichend Innenabstand haben, um system_app_widget_background_radius-Radiuswerte bis zu 28dp zu unterstützen. Andernfalls wird der Inhalt durch die abgerundeten Ecken abgeschnitten.

Für die Widget-Kompatibilität mit früheren Android-Versionen empfehlen wir, benutzerdefinierte Attribute zu definieren und ein benutzerdefiniertes Theme zu verwenden, um sie für Android 12 zu überschreiben, wie in den folgenden Beispiel-XML-Dateien gezeigt:

/values/attrs.xml

<resources>
  <attr name="backgroundRadius" format="dimension" />
</resources>

/values/styles.xml

<resources>
  <style name="MyWidgetTheme">
    <item name="backgroundRadius">@dimen/my_background_radius_dimen</item>
  </style>
</resources>

/values-31/styles.xml

<resources>
  <style name="MyWidgetTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
    <item name="backgroundRadius">@android:dimen/system_app_widget_background_radius</item>
  </style>
</resources>

/drawable/my_widget_background.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="rectangle">
  <corners android:radius="?attr/backgroundRadius" />
  ...
</shape>

/layout/my_widget_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  ...
  android:background="@drawable/my_widget_background" />