A simple composable to display RemoteViews inside your app or to create @Preview
s that together
with Compose and Live Edits
enables, in most situations, a real-time
update mechanism, reflecting code changes nearly instantaneously.
Currently there is an issue that Live Edit stops working after the first change. It actually updates the code but it does not render the update. To workaround you can click on the AppWidgetHost container to force the update.
Note: This library is used by the appwidget-viewer and appwidget-configuration modules and is independent from Glance-appwidget but provides extensions when glance-appwidget dependency is present in the project
repositories {
mavenCentral()
}
dependencies {
// or debugImplementation if only used for previews
implementation "com.google.android.glance.tools:appwidget-host:<version>"
}
Add the AppWidgetHost
inside your UI by providing the available size for the AppWidget and the
AppWidgetHostState
to interact with the host.
You can monitor the isReady
value to then provide the RemoteViews to display in the host.
@Composable
fun MyScreen(provider: AppWidgetProviderInfo) {
val previewHostState = rememberAppWidgetHostState(provider)
if (previewHostState.isReady) {
previewHostState.updateAppWidget(
// Provide your RemoteViews
)
}
AppWidgetHost(
modifier = Modifier.fillMaxSize().padding(16.dp),
widgetSize = DpSize(200.dp, 200.dp),
state = previewHostState
)
}
Important: when using the
AppWidgetHost
inside an activity with AppCompat theme the host won't be able to inflate the RemoteViews. This is because appcompat theme will switch the views to be appcompat views and those are not supported by RemoteViews. Few options:
- Use a different activity
- Remove the theme (or set
android:viewInflaterClass=@null
)- Implement your own
AppCompatViewInflater
The AppWidgetHostPreview
enables Jetpack Compose Live Previews
by creating a @Preview
composable and running it in a device.
Note: while the preview will render in Android Studio, the RemoteViews won't. You must always deploy them in a device (guide).
@Preview
@Composable
fun MyAppWidgetPreview() {
// The size of the widget
val displaySize = DpSize(200.dp, 200.dp)
AppWidgetHostPreview(
modifier = Modifier.fillMaxSize(),
displaySize = displaySize
) { context ->
RemoteViews(context.packageName, R.layout.my_widget_layout)
}
}
If you use Glance for appwidget instead, the library provides an extension composable to simplify the setup
@OptIn(ExperimentalGlanceRemoteViewsApi::class)
@Preview
@Composable
fun MyGlanceWidgetPreview() {
// The size of the widget
val displaySize = DpSize(200.dp, 200.dp)
// Your GlanceAppWidget instance
val instance = SampleGlanceWidget
// Provide a state depending on the GlanceAppWidget state definition
val state = preferencesOf(SampleGlanceWidget.countKey to 2)
GlanceAppWidgetHostPreview(
modifier = Modifier.fillMaxSize(),
glanceAppWidget = instance,
state = state,
displaySize = displaySize,
)
}
Important: don't forget to setup the compose-tooling as explained here
The library also provides a set of common utils when working with AppWidgets and/or Glance:
Snapshots of the development version are available in Sonatype's snapshots
repository.
These are updated on every commit.