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

Cómo declarar el AppWidget en el manifiesto

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

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

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

Agrega los metadatos de 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 información del widget de la app en el archivo @xml/my_app_widget_info.

    La única diferencia de Outline es que no hay XML initialLayout, pero debes definir uno. Puedes usar el diseño de carga predefinido que se proporciona en 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 método provideGlance. Este es el método en el que puedes cargar los datos necesarios 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 glanceAppWidget, en tu GlanceAppWidgetReceiver:

class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {

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

Ya configuraste un objeto AppWidget con Resumen.

Cómo crear una 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<MainActivity>()
                )
                Button(
                    text = "Work",
                    onClick = actionStartActivity<MainActivity>()
                )
            }
        }
    }
}

En la muestra de código anterior, se hace lo siguiente:

  • En el Column de nivel superior, los elementos se colocan uno tras otro de forma vertical.
  • Column expande su tamaño para que coincida con el espacio disponible (a través de GlanceModifier, 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 padding.
    • El segundo elemento es una Row, en la que los elementos se colocan uno tras otro de forma horizontal, 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:
destination_widget
Figura 1: Una IU de ejemplo.

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