In den folgenden Abschnitten wird beschrieben, wie Sie mit Glance ein einfaches App-Widget erstellen.
AppWidget im Manifest deklarieren
Nachdem Sie die Einrichtungsschritte ausgeführt haben, deklarieren Sie das AppWidget und seine
Metadaten in Ihrer App.
Erweitern Sie den
AppWidget-Empfänger vonGlanceAppWidgetReceiver:class MyAppWidgetReceiver : GlanceAppWidgetReceiver() { override val glanceAppWidget: GlanceAppWidget = TODO("Create GlanceAppWidget") }
Registrieren Sie den Anbieter des App-Widgets in der Datei
AndroidManifest.xmlund 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 zum Erstellen eines Widgets, um die App
-Widget-Informationen in der @xml/my_app_widget_info Datei zu erstellen und zu definieren.
Der einzige Unterschied bei Glance besteht darin, dass es kein initialLayout-XML gibt, das Sie aber definieren müssen. Sie können das vordefinierte Ladelayout verwenden, das in der Bibliothek bereitgestellt wird:
<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 AppWidgetProviderInfo in der XML-Metadatenressourcendatei
(res/xml/my_app_widget_info.xml) in einem <appwidget-provider> Element:
<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 Widgetgröße
Die Standardpositionen für Widgets auf dem Startbildschirm werden in einem Fenster basierend auf einem Raster aus Zellen mit einer definierten Höhe und Breite festgelegt. Auf den meisten Startbildschirmen können Widgets nur Größen annehmen, die ganzzahlige Vielfache der Rasterzellen sind, z. B. zwei Zellen horizontal und drei Zellen vertikal.
Mit den Attributen für die Widgetgröße können Sie eine Standardgröße für Ihr Widget angeben und untere und obere Grenzwerte für die Größe des Widgets festlegen. 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 beschrieben, die sich auf die Widgetgröße beziehen:
| 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. Wenn die Attribute
targetCellWidth und targetCellHeight Vorrang haben, haben sie 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 unleserlich oder anderweitig unbrauchbar ist. Mit diesen Attributen kann der Nutzer die Größe des Widgets auf eine Größe verkleinern, 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ößenänderung nicht aktiviert ist. Siehe
resizeMode. Ebenso wird das
minResizeHeight Attribut ignoriert, wenn es größer als
minHeight ist oder wenn die vertikale Größenänderung nicht aktiviert ist. |
maxResizeWidth und
maxResizeHeight |
Geben Sie die empfohlene maximale Größe des Widgets an. Wenn die Werte kein Vielfaches der Abmessungen der Rasterzellen 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ößenänderung nicht
aktiviert ist. Siehe resizeMode. Ebenso wird das maxResizeHeight Attribut ignoriert, wenn es kleiner als minHeight ist oder wenn die vertikale Größenänderung nicht aktiviert ist.
In Android 12 eingeführt. |
resizeMode |
Gibt die Regeln an, nach denen die Größe eines Widgets geändert werden kann. Mit diesem
Attribut können Sie die Größe von Widgets auf dem Startbildschirm horizontal, vertikal,
oder auf beiden Achsen ändern. Nutzer halten ein Widget gedrückt, um die Ziehpunkte für die Größenänderung anzuzeigen,
und ziehen dann die horizontalen oder vertikalen Ziehpunkte, um die Größe im
Layoutraster zu ändern. Zu den Werten für das Attribut resizeMode gehören
horizontal, vertical und none. Wenn Sie ein Widget als horizontal und vertikal anpassbar deklarieren möchten, verwenden Sie
horizontal|vertical. |
Beispiel
Um zu veranschaulichen, wie sich die Attribute in der vorherigen Tabelle auf die Widgetgröße auswirken, nehmen wir die folgenden Spezifikationen an:
- Eine Rasterzelle ist 30 dp breit und 50 dp hoch.
- Die folgende Attributspezifikation wird bereitgestellt:
<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 verkleinert oder auf 4 × 3 vergrößert werden.
Android 11 und niedriger :
Verwenden Sie die Attribute minWidth und minHeight, um die Standardgröße des Widgets zu berechnen.
Standardbreite = Math.ceil(80 / 30) = 3
Standardhöhe = Math.ceil(80 / 50) = 2
Die Standardgröße des Widgets ist 3 × 2. Die Größe des Widgets kann auf 2 × 1 verkleinert oder auf Vollbildgröße vergrößert werden.
Zusätzliche Widgetattribute
In der folgenden Tabelle werden die <appwidget-provider> Attribute beschrieben, die sich auf andere Eigenschaften als die Widgetgröße beziehen.
| Attribute und Beschreibung | |
|---|---|
updatePeriodMillis |
Defines how often the widget framework requests an update from the
GlanceAppWidgetReceiver by calling the onUpdate()
callback method. Wir empfehlen, so selten wie möglich zu aktualisieren, höchstens einmal pro Stunde, um den Akku zu schonen.
Weitere Informationen finden Sie im Abschnitt Wann sollten Widgets aktualisiert werden? unter Glance-Statusverwaltung. |
initialLayout |
Verweist auf die Layoutressource, die das Ladelayout des Widgets definiert, bevor die Glance-UI-Kompositionen gerendert werden. Sie können das vordefinierte Ladelayout verwenden, das in der Bibliothek bereitgestellt wird: @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-Konfigurationsaktivität implementieren auf dieser Seite. |
description |
Gibt die Beschreibung an, die in der Widget-Auswahl für Ihr Widget angezeigt werden soll. In Android 12 eingeführt. |
previewLayout (Android 12)
und previewImage (Android 11 und niedriger) |
|
autoAdvanceViewId |
Gibt die Ansichts-ID der Widget-Unteransicht an, die vom Host des Widgets automatisch weitergeleitet wird. |
widgetCategory |
Gibt an, ob Ihr Widget auf dem Startbildschirm
(home_screen), dem Sperrbildschirm (keyguard) oder beiden angezeigt werden kann. Für Android 5.0 und höher ist nur home_screen gültig. |
widgetFeatures |
Gibt die vom Widget unterstützten Funktionen an. 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
finden Sie unter Coroutinen für die Hauptthread-Sicherheit verwenden.GlanceAppWidgetabgeleitet wird, und überschreibt dieprovideGlanceMethode. 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
glanceAppWidgetin IhremGlanceAppWidgetReceiver:class MyAppWidgetReceiver : GlanceAppWidgetReceiver() { // Let MyAppWidgetReceiver know which GlanceAppWidget to use override val glanceAppWidget: GlanceAppWidget = MyAppWidget() }
Sie haben jetzt ein AppWidget mit Glance konfiguriert.
Klasse „GlanceAppWidgetReceiver“ zum Verarbeiten von Widget-Broadcasts verwenden
Der GlanceAppWidgetReceiver koordiniert Widget-Broadcasts und Plattformstatus
aktualisierungen, indem er den zugrunde liegenden AppWidgetProvider erweitert. Er 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 GlanceAppWidgetReceiver als Broadcast-Empfänger in der Datei AndroidManifest.xml:
<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>
Das <receiver> Element erfordert das android:name Attribut, das
die Empfängerklasse angibt. Der Empfänger muss die ACTION_APPWIDGET_UPDATE
Broadcast-Aktion im <intent-filter> akzeptieren.
Das <meta-data> Element muss als Name
android.appwidget.provider angeben und das android:resource Attribut muss auf
Ihre XML-Metadatenressource AppWidgetProviderInfo (@xml/my_app_widget_info) verweisen.
Klasse „GlanceAppWidgetReceiver“ implementieren
In Glance erweitern Sie GlanceAppWidgetReceiver anstelle von AppWidgetProvider direkt. Implementieren Sie es, indem Sie Ihren Empfänger 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 Kompositionsaktualisierungen 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 geändert wird. Glance liest Options-Bundle-Elemente im Hintergrund, sodass Ihr Layout nahtlos an die Laufzeitdimensionen angepasst wird.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. Ideal für die Ausführung globaler Migrationen.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 sicherstellen, dass jede benutzerdefinierte Empfängerlogik die Sie schreiben,super.onReceive(context, intent)aufruft und niemals selbstgoAsyncaufruft, da Glance die Arbeit automatisch asynchron weiterleitet.
Widget-Broadcast-Intents empfangen
Im Hintergrund filtert und verarbeitet GlanceAppWidgetReceiver die folgenden grundlegenden Widget-Broadcast-Intents der Plattform:
ACTION_APPWIDGET_UPDATEACTION_APPWIDGET_DELETEDACTION_APPWIDGET_ENABLEDACTION_APPWIDGET_DISABLEDACTION_APPWIDGET_OPTIONS_CHANGED
UI erstellen
Das folgende Snippet zeigt, wie Sie die UI erstellen:
/* 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 vorherige Codebeispiel führt folgende Schritte aus:
- In der obersten Ebene
Columnwerden Elemente vertikal nacheinander platziert. - Die
Columnwird so erweitert, dass sie dem verfügbaren Platz entspricht (über dieGlanceModifier), und der Inhalt wird oben (verticalAlignment) und horizontal zentriert (horizontalAlignment) ausgerichtet. - Der Inhalt der
Columnwird mit der Lambda-Funktion definiert. Die Reihenfolge ist wichtig.- Das erste Element in der
Columnist eineText-Komponente mit einem Abstand von12.dp. - Das zweite Element ist eine
Row, in der Elemente horizontal nacheinander platziert werden, mit zweiButtons, die horizontal zentriert sind (horizontalAlignment). Die endgültige Anzeige hängt vom verfügbaren Platz ab. Die folgende Abbildung zeigt ein Beispiel dafür, wie das aussehen kann:
- Das erste Element in der
Sie können die Ausrichtungswerte ändern oder verschiedene Modifikatorwerte (z. B. Abstand) anwenden, um die Platzierung und Größe der Komponenten zu ändern. Eine vollständige Liste der Komponenten, Parameter und verfügbaren Modifikatoren für jede Klasse finden Sie in der Referenz dokumentation.
Abgerundete Ecken implementieren
In Android 12 werden Systemparameter eingeführt, mit denen Sie die Eckradien Ihrer App-Widgets dynamisch anpassen können:
system_app_widget_background_radius: Gibt den Eckradius des Widget-Hintergrundcontainers an (nie größer als 28 dp).- Innenradius:Um zu verhindern, dass Inhalte abgeschnitten werden, berechnen Sie einen proportionalen Radius für Ihre internen Inhalte basierend auf der Systemhintergrundkontur:
systemRadiusValue - widgetPadding
In Glance können Sie Eigenschaften für die Eckradiusgröße dynamisch in der Komposition mit GlanceModifier.cornerRadius(android.R.dimen.system_app_widget_background_radius) anwenden.
Für die Abwärtskompatibilität auf Geräten mit Android 11 (API-Level 30) oder niedriger implementieren Sie benutzerdefinierte Attribute und Fallbacks für benutzerdefinierte Designressourcen:
/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>