Configuring a Jetpack Compose Widget Using Glance

Murad Hamidov
2 min readMar 10, 2024
screens

If you’re diving into the world of Jetpack Compose and want to create a widget for your Android app, you’re in the right place. In this guide, we’ll set up a widget using Jetpack Compose.

Prerequisites

Before we begin, make sure you have the following dependencies in your build.gradle file:

//widget
implementation("androidx.glance:glance:1.1.0-alpha01")
implementation("androidx.glance:glance-appwidget:1.1.0-alpha01")

Manifest Setup

In your AndroidManifest.xml, declare the receiver for your widget:

<receiver android:name=".widget.CounterWidgetReceiver" 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/counter_widget_info" />
</receiver>

Widget Provider Configuration

Create a widget provider XML file (xml/counter_widget_info.xml) with the necessary configurations:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/app_name"
android:minWidth="130dp"
android:minHeight="102dp"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen"
/>

GlanceAppWidget

The widget is represented by the TrackerWidget object, extending the GlanceAppWidget:

object TrackerWidget: GlanceAppWidget() {

// Constants and preferences keys
// ...
const val KEY_WIDGET_COUNT = "count"
val countKey = intPreferencesKey(KEY_WIDGET_COUNT)

override suspend fun provideGlance(context: Context, id: GlanceId) {
// Widget content generation logic
// ...
provideContent {
val count = currentState(key = countKey) ?: preferences.getCount()
val goal = 10
val countPercent = count * 100 / goal
context.WidgetContent(count,countPercent)

}
}
}

In this implementation, TrackerWidget inherits from GlanceAppWidget, a part of the Glance library. The GlanceAppWidget provides a framework for building glanceable widgets with simplified configuration and state management.

By extending GlanceAppWidget, you gain access to convenient functions for handling widget states, preferences, and content updates. The provideGlance function is where you define the logic for generating widget content based on the current state and user preferences.

Widget Receiver

Handle widget updates in the CounterWidgetReceiver class:

class CounterWidgetReceiver: GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget
get() = TrackerWidget
}

Action Callback for Incrementing

Implement an action callback (IncrementActionCallback) to handle widget interactions:

class IncrementActionCallback: ActionCallback {
override suspend fun onAction(context: Context, glanceId: GlanceId, parameters: ActionParameters) {


updateAppWidgetState(context, glanceId) { prefs ->
val currentCount = prefs[TrackerWidget.countKey]

currentCount?.let {
prefs[TrackerWidget.countKey] = currentCount + 1
}?: run{
prefs[TrackerWidget.countKey] = 1
}

}
TrackerWidget.update(context, glanceId)
}
}

Composable Content

Define the Composable functions for rendering widget content:

@Composable
fun Context.WidgetContent(count: Int, countPercent: Int) {
// Composable content for widget with increment button

Column(
modifier = GlanceModifier
.fillMaxSize().padding(4.dp)
.background(White),
verticalAlignment = Alignment.Vertical.CenterVertically,
horizontalAlignment = Alignment.Horizontal.CenterHorizontally
) {

Button(
text = getString(R.string.add_1),
colors = ButtonDefaults.buttonColors(
backgroundColor = ColorProvider(Blue),
ColorProvider(White)
),
onClick = actionRunCallback(IncrementActionCallback::class.java)
)

// ...

}
}

Ensure the correct import statements:

import androidx.glance.Button 
import androidx.glance.Text
//or
import androidx.glance.*

That’s it! You’ve configured a Jetpack Compose widget using Kotlin and Glance. Feel free to customize the code according to your app’s requirements.

For a closer look at the sample code and to contribute to the project, check out the GitHub repository:

GitHub Repository — (Drops Water Tracker)

Your feedback and contributions are highly appreciated. Happy coding!

--

--