Setting Up home_widget in Flutter [android — XML/Glance]
Let’s dive into the world of interactive Android widgets! Today, we’ll start by setting up everything needed to create sleek and functional widgets for Android devices using Flutter.
We’ll use home_widget
package to make the implementation of widgets simpler.
flutter pub add home_widget
Setup
We can develop widgets using XML or Jetpack glance
- Using XML
1. Open the Android module in Android Studio.
2. Right-click on ‘app’ -> New -> Widget -> App Widget
3. Fill desired details in a prompt
You can modify these options later also.
4. After creating the widget you may get an error of Kotlin Gradle plugin version
> Cannot resolve external dependency org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.22 because no repositories are defined.
Go to android > build.gradle
and comment/remove the mentioned plugin version, and run the Flutter project once —
dependencies {
// classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.22'
}
- ensure you are using minSdkVersion 21
5. Android Studio will create the necessary files for creating the widget, from those, let’s move the Implementation of App Widget functionality (AppWidgetDemo.kt) file from app -> main -> java
to the folder com.example.demo.home_widget_demo
which is under kotlin folder
6. In AppWidgetDemo.kt
change AppWidgetProvider
with HomeWidgetProvider
class. Also, pass SharedPreferences
(to interact with data in flutter) as shown —
7. Finally, run the Flutter project, and you will be able to see the widget option for your app
8. To launch the app by clicking the widget, open AppWidgetDemo.kt
and in the updateAppWidget
function, add apply() { ... }
to RemoteViews() as shown below.
[ here, I’m targeting click, which will be on text using R.id.appwidget_text
]
val views = RemoteViews(context.packageName, R.layout.app_widget_demo).apply() {
val pendingIntent = HomeWidgetLaunchIntent.getActivity(
context,
MainActivity::class.java)
setOnClickPendingIntent(
R.id.appwidget_text,
pendingIntent
)
}
- Using Glance
1. In android/app/build.gradle
add dependencies —
dependencies {
implementation "androidx.glance:glance:1.1.1"
}
In the same build.gradle
, Activate compose compiler by adding following
android {
...
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.8"
}
...
}
for the latest version refer release page.
2. Define simple app widget and info of that widget in app_widget_demo.xml
inside xml
folder
Example code —
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/glance_default_loading_layout"
android:minWidth="100dp"
android:minHeight="100dp"
android:resizeMode="none"
android:updatePeriodMillis="500"
android:widgetCategory="home_screen">
</appwidget-provider>
3. Let’s code a simple app widget with a glance. Create the Kotlin file AppWidgetdemo.kt
in kotlin folder of the app
package com.example.home_widget_glance
import android.content.Context
import androidx.glance.appwidget.GlanceAppWidget
import androidx.compose.runtime.Composable
...
class MyAppWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
// add your own widget here
MyContent(context)
}
}
@Composable
private fun MyContent(context: Context) {
Box(
modifier = GlanceModifier.background(Color.White).padding(16.dp)
.clickable(onClick = actionStartActivity<MainActivity>(context))
) {
Column(
modifier = GlanceModifier.fillMaxSize(),
verticalAlignment = Alignment.Vertical.CenterVertically,
horizontalAlignment = Alignment.Horizontal.CenterHorizontally,
) {
Text(
"Hello Flutter!",
style = TextStyle(
fontSize = 32.sp,
textAlign = TextAlign.Center,
fontWeight = FontWeight.Bold,
),
)
}
}
}
}
4. Make AppWidgetDemoReceiver.kt
in the same folder, which will handle updating behaviour of the widget.home_widget
provides an abstraction for this, so we only need to provide simple references to the Widget
package com.example.home_widget_glance
import HomeWidgetGlanceWidgetReceiver
class MyAppWidgetReceiver : HomeWidgetGlanceWidgetReceiver<MyAppWidget>() {
override val glanceAppWidget = MyAppWidget() // pass created widget here
}
5. Now, Registering the MyAppWidgetReceiver
in our AndroidManifest.xml
file and the associated metadata file
<application>
...
<receiver android:name=".MyAppWidgetReceiver"
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_demo" />
</receiver>
...
</application>
6. Run the Flutter project, you’ll be able to see the widget option for the app
Setup is Done!
That’s all for now. Thank you for reading this article👏
See you next time 👍.