2

Building a widget using Jetpack Glance

 2 years ago
source link: https://proandroiddev.com/building-a-widget-using-jetpack-glance-59317dfbfe9
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Building a widget using Jetpack Glance

App widgets are miniature application views that can be embedded in the home screen of your device. Jetpack Glance is a library built on top of Jetpack Compose that allows you to build these widgets for Android.

1*D_f8oDgrxRkRhWrX1OMOrQ.png

In the above image you can see a weather widget.

0*rNFOj0ZsVkwW2zJf.jpg

In this other example, you can see a music app widget that allows you to control the music playback.

In this tutorial we’ll create a quotes widget.

Setup

Jetpack Glance was released in 2021 and as of now, it has a release candidate.

Before we start make sure you have Jetpack Compose enabled.

android {
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.1.0-beta03"
}
kotlinOptions {
jvmTarget = "1.8"
}
}

Then include the dependencies for Glance.

dependencies {
implementation "androidx.glance:glance:1.0.0-rc01"
implementation "androidx.glance:glance-appwidget:1.0.0-rc01"
}

The first thing we need to do is to define an app widget provider. Create a file named app_widget_provider.xml inside res/xml.

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="100dp"
android:minHeight="100dp" />

There are many attributes you can define, if you want to learn more about them you can read this documentation.

After that we need to create our widget.

class QuotesWidget : GlanceAppWidget() {

override val stateDefinition: GlanceStateDefinition<*> = PreferencesGlanceStateDefinition
override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
Text(text = "Hello World!")
}
}
}

The main thing here is the provideGlance function, that's where you define which composable you want displayed.

Make sure you import the composables from Glance. For example you need to use androidx.glance.text.Text instead of androidx.compose.material3.Text.

After that we need to declare our receiver.

class QuotesWidgetReceiver : GlanceAppWidgetReceiver() {

override val glanceAppWidget: GlanceAppWidget = QuotesWidget()

}

Now go to your AndroidManifest and import the receiver you just declared.

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>

<application ...>
<receiver
android:name=".QuotesWidgetReceiver"
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/app_widget_provider" />
</receiver>
</application>

</manifest>

If you don’t have an activity you need to modify Android Studio so it runs without one. First go to your run configuration.

0*42idFUKZWZ6kEZBb.png

Then select “Always install with package manager” and change “Launch:” to “Nothing”.

0*FSUkTucy_3TUtNQ4.png

After that you should be able to run the app. Open the widgets screen and find your widget there.

0*OwpN341yo99_NTKE.png

Now that we already have a widget, let’s add some functionality to it.

private val quotes = listOf(
"Be yourself; everyone else is already taken. ― Oscar Wilde",
"A room without books is like a body without a soul. ― Marcus Tullius Cicero",
"You only live once, but if you do it right, once is enough. ― Mae West",
)

private val currentQuoteKey = stringPreferencesKey("currentQuote")

class QuotesWidget : GlanceAppWidget() {

override val stateDefinition: GlanceStateDefinition<*> = PreferencesGlanceStateDefinition

override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
val preferences = currentState<Preferences>()
val currentQuote = preferences[currentQuoteKey] ?: quotes.random()

MaterialTheme {
Box(
modifier = GlanceModifier
.background(Color.White)
.padding(16.dp)
.clickable(actionRunCallback<RefreshQuoteAction>())
) {
Text(text = currentQuote)
}
}
}
}

}

class RefreshQuoteAction : ActionCallback {

override suspend fun onAction(
context: Context,
glanceId: GlanceId,
parameters: ActionParameters
) {
updateAppWidgetState(context, PreferencesGlanceStateDefinition, glanceId) { preferences ->
preferences.toMutablePreferences().apply {
this[currentQuoteKey] = quotes.random()
}
}
QuotesWidget().update(context, glanceId)
}
}

Run the widget again and you’ll see a quote. Tap the widget and it’ll display a different quote.

0*NOwP4gQN8nE1o1Ae.png

If you want to learn more about widgets you can follow the Android documentation.

Photo by Vincent LaVigna on Unsplash

</div


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK