Glance simplifies handling user interaction via the Action
classes. Glance's
Action
classes define the actions a user can take, and you can specify the
operation performed in response to the action. You can apply an Action
to any
component with the GlanceModifier.clickable
method.
App widgets live on a remote process, so the actions are defined at creation
time and the execution happens in the remote process. In native RemoteViews
,
this is done via PendingIntents
.
The following actions are described on this page:
Launch an activity
To launch an activity on user interaction, provide the
actionStartActivity
function to a Button
or other composable via the
GlanceModifier.clickable
(..) modifier.
Provide one of the following in actionStartActivity
:
- The target activity class
- The
ComponentName
- An Intent
Glance translates the Action into a PendingIntent
with the provided target and
parameters. In the following example, the NavigationActivity
is launched when a
user clicks the button:
@Composable fun MyContent() { // .. Button( text = "Go Home", onClick = actionStartActivity<MyActivity>() ) }
Launch a service
Similar to launching an activity, launch a service on user interaction using one
of the actionStartService
methods.
Provide one of the following in actionStartService
:
- The target activity class
- The
ComponentName
- An intent
@Composable fun MyButton() { // .. Button( text = "Sync", onClick = actionStartService<SyncService>( isForegroundService = true // define how the service is launched ) ) }
Send a broadcast event
Send a broadcast event on user interaction using one of the
actionSendBroadcast
methods:
Provide one of the following in actionSendBroadcast
:
- String action
- The
ComponentName
- An intent
BroadcastReceiver
class
@Composable fun MyButton() { // .. Button( text = "Send", onClick = actionSendBroadcast<MyReceiver>() ) }
Perform custom actions
Instead of launching a specific target, Glance can use a lambda action or an
actionRunCallback
to perform an action, such as updating the UI or state on
user interaction.
Run lambda actions
You can use lambda functions as callbacks to the UI interactions.
For example, pass the lambda function to the GlanceModifier.clickable
modifier:
Text( text = "Submit", modifier = GlanceModifier.clickable { submitData() } )
Or, pass it to the onClick
parameter on composables that support it:
Button( text = "Submit", onClick = { submitData() } )
Run ActionCallback
Alternatively, use the actionRunCallback
methods to perform an action on
user interaction. To do this, provide a custom implementation of the
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 } }
On the user click, the suspend onAction
method of the provided
ActionCallback
is called, executing the defined logic (i.e., requesting
refresh data).
To update the widget after the action is performed, create a new instance and
call update
(..). For more details, see the Manage GlanceAppWidget state
section.
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) } }
Provide parameters to actions
To provide additional information to an action, use the ActionParameters
API to create a typed key-value pair. For example, to define the clicked
destination:
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() } } }
Underneath, the parameters are included in the intent used to launch the activity, allowing the target Activity to retrieve it.
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val destination = intent.extras?.getString(KEY_DESTINATION) ?: return // ... } }
The parameters are also provided to the ActionCallback
. Use the defined
Parameters.Key
to retrieve the value:
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 // ... } }