Manifest, Metadaten
In den folgenden Abschnitten wird beschrieben, wie Sie mit Glance ein einfaches App-Widget erstellen.
AppWidget im Manifest deklarieren
Nachdem Sie die Einrichtungsschritte abgeschlossen haben, deklarieren Sie das AppWidget und seine Metadaten in Ihrer App.
Erweitere den
AppWidget-Empfänger vonGlanceAppWidgetReceiver:class MyAppWidgetReceiver : GlanceAppWidgetReceiver() { override val glanceAppWidget: GlanceAppWidget = TODO("Create GlanceAppWidget") }
Registrieren Sie den Anbieter des App-Widgets in Ihrer
AndroidManifest.xml-Datei und der zugehörigen Metadatendatei:<receiver android:name=".glance.MyReceiver" android:exported="true"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/my_app_widget_info" /> </receiver>
AppWidgetProviderInfo-Metadaten hinzufügen
Folgen Sie als Nächstes der Anleitung unter Widget erstellen, um die App-Widget-Informationen in der Datei @xml/my_app_widget_info zu erstellen und zu definieren.
Der einzige Unterschied für Glances besteht darin, dass es kein initialLayout-XML gibt, Sie aber eines definieren müssen. Sie können das vordefinierte Lade-Layout aus der Bibliothek verwenden:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/glance_default_loading_layout">
</appwidget-provider>
AppWidgetProviderInfo-XML deklarieren
Das AppWidgetProviderInfo-Objekt definiert die wesentlichen Eigenschaften Ihres Widgets. Definieren Sie die AppWidgetProviderInfo in Ihrer XML-Metadatenressourcendatei (res/xml/my_app_widget_info.xml) innerhalb eines <appwidget-provider>-Elements:
<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/glance_default_loading_layout"
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 einem Fenster auf Grundlage eines Rasters 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 |
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 anpassen, 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. Siehe resizeMode. Ebenso wird das Attribut maxResizeHeight ignoriert, wenn es kleiner als minHeight ist oder 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 halten ein Widget gedrückt, 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 Widget-Größe 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. Die Größe des Widgets kann auf 2 × 1 oder auf Vollbild geändert 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 GlanceAppWidgetReceiver anfordert, indem die Callback-Methode onUpdate() aufgerufen wird. Wir empfehlen, die Daten so selten wie möglich zu aktualisieren, um den Akku zu schonen. Aktualisieren Sie die Daten nicht öfter als einmal pro Stunde.
Weitere Informationen finden Sie im Abschnitt Glance-Statusverwaltung unter „Wann Widgets aktualisiert werden“. |
initialLayout |
Verweist auf die Layoutressource, die das Ladelayout des Widgets definiert, bevor die Glance-UI-Kompositionen gerendert werden. Sie können das in der Bibliothek bereitgestellte vordefinierte Lade-Layout verwenden: @layout/glance_default_loading_layout. |
configure |
Definiert die Konfigurationsaktivität, die gestartet wird, wenn der Nutzer das Widget hinzufügt. Weitere Informationen finden Sie im Abschnitt Widget-Konfigurations-Activity implementieren auf dieser Seite. |
description |
Gibt die Beschreibung an, die für Ihr Widget in der Widget-Auswahl angezeigt werden soll. Eingeführt in Android 12 |
previewLayout (Android 12)
und previewImage (Android 11 und niedriger) |
|
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 |
Deklariert die vom Widget unterstützten Funktionen. Wenn die Konfiguration Ihres Widgets beispielsweise optional ist, geben Sie sowohl configuration_optional als auch reconfigurable an. |
GlanceAppWidget definieren
Erstellen Sie eine neue Klasse, die von
GlanceAppWidgetabgeleitet wird und die MethodeprovideGlanceüberschreibt. Mit dieser Methode können Sie Daten laden, die zum Rendern Ihres Widgets erforderlich sind:class MyAppWidget : GlanceAppWidget() { override suspend fun provideGlance(context: Context, id: GlanceId) { // In this method, load data needed to render the AppWidget. // Use `withContext` to switch to another thread for long running // operations. provideContent { // create your AppWidget here Text("Hello World") } } }
Instanziieren Sie sie in der
glanceAppWidgetauf IhremGlanceAppWidgetReceiver:class MyAppWidgetReceiver : GlanceAppWidgetReceiver() { // Let MyAppWidgetReceiver know which GlanceAppWidget to use override val glanceAppWidget: GlanceAppWidget = MyAppWidget() }
Sie haben jetzt eine AppWidget mit Glance konfiguriert.
AppWidgetProvider-Klasse zum Verarbeiten von Widget-Broadcasts verwenden
Das GlanceAppWidgetReceiver-Koordinaten-Widget überträgt Broadcasts und Plattformstatus-Updates, indem es die zugrunde liegende AppWidgetProvider erweitert. Sie empfängt Plattformereignisse, wenn Ihr Widget aktualisiert, gelöscht, aktiviert oder deaktiviert wird, und übersetzt sie in Compose-Lebenszyklusanfragen.
Widget im Manifest deklarieren
Deklarieren Sie die Unterklasse Ihrer GlanceAppWidgetReceiver-Klasse als Übertragungsempfänger in Ihrer AndroidManifest.xml-Datei:
<receiver android:name="ExampleAppWidgetReceiver"
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/my_app_widget_info" />
</receiver>
Für das <receiver>-Element ist das Attribut android:name erforderlich, das die Empfängerklasse angibt. Der Empfänger muss die ACTION_APPWIDGET_UPDATE-Broadcast-Aktion in der <intent-filter> akzeptieren.
Das <meta-data>-Element muss seinen Namen als android.appwidget.provider angeben und das Attribut android:resource muss auf Ihre AppWidgetProviderInfo-XML-Metadatenressource (@xml/my_app_widget_info) verweisen.
AppWidgetProvider-Klasse implementieren
In Glance erweitern Sie GlanceAppWidgetReceiver anstelle von AppWidgetProvider. Implementieren Sie sie, indem Sie Ihren Receiver mit Ihrer GlanceAppWidget-Instanz verknüpfen. Die primären Callbacks, die in GlanceAppWidgetReceiver verfügbar sind, funktionieren so:
onUpdate(): Wird automatisch von Glance überschrieben, um Kompositionsupdates auszuführen. Wenn SieonUpdatemanuell überschreiben, müssen Siesuper.onUpdateaufrufen, damit Glance Kompositionsthreads erfolgreich starten kann.onAppWidgetOptionsChanged(): Wird aufgerufen, wenn das Widget zum ersten Mal platziert oder in der Größe angepasst wird. Bei Glance-Lesevorgängen werden Elemente im Hintergrund gebündelt, sodass sich das Layout basierend auf den Laufzeitdimensionen nahtlos anpasst.onDeleted(Context, IntArray): Wird aufgerufen, wenn eine bestimmte Widget-Instanz vom Nutzer gelöscht wird.onEnabled(Context): Wird ausgelöst, wenn die erste Instanz Ihres Widgets erfolgreich erstellt wurde. Hervorragend für globale Migrationen geeignet.onDisabled(Context): Wird aufgerufen, wenn die letzte aktive Instanz des Anbieters entfernt wird.onReceive(Context, Intent): Fängt jeden Plattform-Broadcast vor bestimmten Callback-Methoden ab. Sie müssen dafür sorgen, dass in der benutzerdefinierten Empfängerlogik, die Sie schreiben,super.onReceive(context, intent)aufgerufen wird undgoAsyncniemals selbst aufgerufen wird, da Glance Aufgaben automatisch asynchron weiterleitet.
Broadcast-Intents für Widgets empfangen
Im Hintergrund filtert und verarbeitet GlanceAppWidgetReceiver die folgenden Broadcast-Intents für grundlegende Plattform-Widgets:
ACTION_APPWIDGET_UPDATEACTION_APPWIDGET_DELETEDACTION_APPWIDGET_ENABLEDACTION_APPWIDGET_DISABLEDACTION_APPWIDGET_OPTIONS_CHANGED
UI erstellen
Das folgende Snippet zeigt, wie die Benutzeroberfläche erstellt wird:
/* Import Glance Composables In the event there is a name clash with the Compose classes of the same name, you may rename the imports per https://kotlinlang.org/docs/packages.html#imports using the `as` keyword. import androidx.glance.Button import androidx.glance.layout.Column import androidx.glance.layout.Row import androidx.glance.text.Text */ class MyAppWidget : GlanceAppWidget() { override suspend fun provideGlance(context: Context, id: GlanceId) { // Load data needed to render the AppWidget. // Use `withContext` to switch to another thread for long running // operations. provideContent { // create your AppWidget here MyContent() } } @Composable private fun MyContent() { Column( modifier = GlanceModifier.fillMaxSize(), verticalAlignment = Alignment.Top, horizontalAlignment = Alignment.CenterHorizontally ) { Text(text = "Where to?", modifier = GlanceModifier.padding(12.dp)) Row(horizontalAlignment = Alignment.CenterHorizontally) { Button( text = "Home", onClick = actionStartActivity<MyActivity>() ) Button( text = "Work", onClick = actionStartActivity<MyActivity>() ) } } } }
Das vorhergehende Codebeispiel führt folgende Schritte aus:
- Auf der obersten Ebene
Columnwerden Elemente vertikal untereinander platziert. - Die
Columnwird so vergrößert, dass sie dem verfügbaren Platz entspricht (überGlanceModifier), und der Inhalt wird oben (verticalAlignment) und horizontal zentriert (horizontalAlignment) ausgerichtet. - Der Inhalt von
Columnwird mit dem Lambda definiert. Die Reihenfolge ist wichtig.- Das erste Element in
Columnist eineText-Komponente mit einem12.dp-Abstand. - Das zweite Element ist ein
Row, in dem Elemente horizontal nebeneinander platziert werden, mit zwei horizontal zentriertenButtons(horizontalAlignment). Die endgültige Darstellung hängt vom verfügbaren Platz ab. Das folgende Bild zeigt ein Beispiel:
- Das erste Element in
Sie können die Ausrichtungswerte ändern oder verschiedene Modifikatorwerte (z. B. Padding) anwenden, um die Position und Größe der Komponenten zu ändern. Eine vollständige Liste der Komponenten, Parameter und verfügbaren Modifizierer für jede Klasse finden Sie in der Referenzdokumentation.
Abgerundete Ecken implementieren
In Android 12 werden Systemparameter eingeführt, mit denen die Eckenradien von App-Widgets dynamisch angepasst werden können:
system_app_widget_background_radius: Gibt den Eckenradius des Hintergrundcontainers des Widgets an (nie größer als 28 dp).- Innerer Radius:Damit Inhalte nicht abgeschnitten werden, berechnen Sie einen proportionalen Radius für Ihre inneren Inhalte basierend auf der Umrisslinie des Systemhintergrunds:
systemRadiusValue - widgetPadding
In Glance können Sie die Größenanpassungseigenschaften für den Eckenradius dynamisch in der Komposition mit GlanceModifier.cornerRadius(android.R.dimen.system_app_widget_background_radius) anwenden.
Zur Abwärtskompatibilität auf Geräten mit Android 11 (API-Level 30) oder niedriger müssen Sie benutzerdefinierte Attribute und Fallbacks für benutzerdefinierte Themenressourcen implementieren:
/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>