Cómo controlar la interacción del usuario

Glance simplifica el manejo de la interacción del usuario con las clases Action. Las clases Action de Glance definen las acciones que puede realizar un usuario, y puedes especificar la operación que se realiza en respuesta a la acción. Puedes aplicar un Action a cualquier componente con el método GlanceModifier.clickable.

Los widgets de la app se encuentran en un proceso remoto, por lo que las acciones se definen en el momento de la creación y la ejecución se produce en el proceso remoto. En RemoteViews nativo, esto se hace con PendingIntents.

En esta página, se describen las siguientes acciones:

Cómo iniciar una actividad

Para iniciar una actividad en la interacción del usuario, proporciona la función actionStartActivity a un Button o a otro elemento componible con el modificador GlanceModifier.clickable.

Proporciona uno de los siguientes elementos en actionStartActivity:

Glance traduce la acción en un PendingIntent con el destino y los parámetros proporcionados. En el siguiente ejemplo, se inicia NavigationActivity cuando un usuario hace clic en el botón:

@Composable
fun MyContent() {
    // ..
    Button(
        text = "Go Home",
        onClick = actionStartActivity<MyActivity>()
    )
}

Inicia un servicio

Al igual que cuando inicias una actividad, inicia un servicio en la interacción del usuario con uno de los métodos actionStartService.

Proporciona uno de los siguientes elementos en actionStartService:

@Composable
fun MyButton() {
    // ..
    Button(
        text = "Sync",
        onClick = actionStartService<SyncService>(
            isForegroundService = true // define how the service is launched
        )
    )
}

Envía un evento de transmisión

Envía un evento de transmisión en la interacción del usuario con uno de los métodos actionSendBroadcast:

Proporciona uno de los siguientes elementos en actionSendBroadcast:

@Composable
fun MyButton() {
    // ..
    Button(
        text = "Send",
        onClick = actionSendBroadcast<MyReceiver>()
    )
}

Cómo realizar acciones personalizadas

En lugar de iniciar un destino específico, Glance puede usar una acción de lambda o un actionRunCallback para realizar una acción, como actualizar la IU o el estado en la interacción del usuario.

Ejecuta acciones de Lambda

Puedes usar funciones lambda como devoluciones de llamada para las interacciones de la IU.

Por ejemplo, pasa la función lambda al modificador GlanceModifier.clickable:

Text(
    text = "Submit",
    modifier = GlanceModifier.clickable {
        submitData()
    }
)

O bien, pásalo al parámetro onClick en los elementos componibles que lo admiten:

Button(
    text = "Submit",
    onClick = {
        submitData()
    }
)

Ejecuta ActionCallback

Como alternativa, usa los métodos actionRunCallback para realizar una acción en la interacción del usuario. Para ello, proporciona una implementación personalizada de ActionCallback:

@Composable
private fun MyContent() {
    // ..
    Image(
        provider = ImageProvider(R.drawable.ic_hourglass_animated),
        modifier = GlanceModifier.clickable(
            onClick = actionRunCallback<RefreshAction>()
        ),
        contentDescription = "Refresh"
    )
}

class RefreshAction : ActionCallback {
    override suspend fun onAction(
        context: Context,
        glanceId: GlanceId,
        parameters: ActionParameters
    ) {
        // TODO implement
    }
}

Cuando el usuario hace clic, se llama al método suspend onAction del ActionCallback proporcionado, lo que ejecuta la lógica definida (es decir, solicitar datos de actualización).

Para actualizar el widget después de que se realice la acción, crea una instancia nueva y llama a update(..). Para obtener más detalles, consulta la sección Administra el estado de GlanceAppWidget.

class RefreshAction : ActionCallback {
    override suspend fun onAction(
        context: Context,
        glanceId: GlanceId,
        parameters: ActionParameters
    ) {
        // do some work but offset long-term tasks (e.g a Worker)
        MyAppWidget().update(context, glanceId)
    }
}

Proporciona parámetros a las acciones

Para proporcionar información adicional a una acción, usa la API de ActionParameters para crear un par clave-valor con tipo. Por ejemplo, para definir el destino en el que se hizo clic, haz lo siguiente:

private val destinationKey = ActionParameters.Key<String>(
    NavigationActivity.KEY_DESTINATION
)

class MyAppWidget : GlanceAppWidget() {

    // ..

    @Composable
    private fun MyContent() {
        // ..
        Button(
            text = "Home",
            onClick = actionStartActivity<NavigationActivity>(
                actionParametersOf(destinationKey to "home")
            )
        )
        Button(
            text = "Work",
            onClick = actionStartActivity<NavigationActivity>(
                actionParametersOf(destinationKey to "work")
            )
        )
    }

    override suspend fun provideGlance(context: Context, id: GlanceId) {
        provideContent { MyContent() }
    }
}

Debajo, los parámetros se incluyen en el intent que se usa para iniciar la actividad, lo que permite que la actividad de destino la recupere.

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val destination = intent.extras?.getString(KEY_DESTINATION) ?: return
        // ...
    }
}

Los parámetros también se proporcionan a la ActionCallback. Usa el Parameters.Key definido para recuperar el valor:

class RefreshAction : ActionCallback {

    private val destinationKey = ActionParameters.Key<String>(
        NavigationActivity.KEY_DESTINATION
    )

    override suspend fun onAction(
        context: Context,
        glanceId: GlanceId,
        parameters: ActionParameters
    ) {
        val destination: String = parameters[destinationKey] ?: return
        // ...
    }
}