Cómo crear un widget de la app con Glance

En las siguientes secciones, se describe cómo crear un widget de app simple con Glance.

Cómo declarar el AppWidget en el manifiesto

Después de completar los pasos de configuración, declara el AppWidget y su metadatos en tu app.

  1. Registra el proveedor del widget de la app en el archivo AndroidManifest.xml. y el archivo de metadatos asociado:
<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>
  1. Extiende el receptor AppWidget de GlanceAppWidgetReceiver:

class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {
    override val glanceAppWidget: GlanceAppWidget = TODO("Create GlanceAppWidget")
}

Agrega los metadatos AppWidgetProviderInfo

Luego, sigue este paso para agregar los metadatos AppWidgetProviderInfo:

  1. Sigue la guía Cómo crear un widget simple para crear y definir la app. información del widget en el archivo @xml/my_app_widget_info.

    La única diferencia para Glance es que no hay XML de initialLayout, pero debes definir uno. Puedes usar el diseño de carga predefinido la biblioteca:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/glance_default_loading_layout">
</appwidget-provider>

Definir GlanceAppWidget

  1. Crea una clase nueva que se extienda desde GlanceAppWidget y anule el provideGlance. Este es el método con el que puedes cargar datos que son necesario para renderizar tu widget:

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")
        }
    }
}

  1. Crea una instancia en el glanceAppWidget de tu GlanceAppWidgetReceiver:

class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {

    // Let MyAppWidgetReceiver know which GlanceAppWidget to use
    override val glanceAppWidget: GlanceAppWidget = MyAppWidget()
}

Configuraste un AppWidget con Glance.

Crear IU

En el siguiente fragmento, se muestra cómo crear la IU:

/* 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
            GlanceTheme {
                MyContent()
            }
        }
    }

    @Composable
    private fun MyContent() {
        Column(
            modifier = GlanceModifier.fillMaxSize()
                .background(GlanceTheme.colors.background),
            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>()
                )
            }
        }
    }
}

La muestra de código anterior hace lo siguiente:

  • En el nivel superior Column, los elementos se colocan de forma vertical, uno después de cada uno. entre sí.
  • Column expande su tamaño para que coincida con el espacio disponible (mediante el GlanceModifier y alinea su contenido con la parte superior (verticalAlignment) y lo centra horizontalmente (horizontalAlignment).
  • El contenido de Column se define con la expresión lambda. El orden es importante.
    • El primer elemento de Column es un componente Text con 12.dp de con padding.
    • El segundo elemento es un Row, en el que los elementos se colocan horizontalmente uno uno detrás de otro, con dos Buttons centrados de forma horizontal horizontalAlignment. La pantalla final depende del espacio disponible. La siguiente imagen es un ejemplo de cómo podría verse:
Widget_de_destino
Figura 1: Ejemplo de IU.

Puedes cambiar los valores de alineación o aplicar diferentes valores de modificador (como con padding) para cambiar la ubicación y el tamaño de los componentes. Consulta la referencia documentación para obtener una lista completa de los componentes, los parámetros y los recursos modificadores de cada clase.