CounterWidget.kt
package com.cfsuman.widgetexamples
import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.glance.*
import androidx.glance.action.ActionParameters
import androidx.glance.action.actionParametersOf
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
import androidx.glance.appwidget.action.ActionCallback
import androidx.glance.appwidget.action.actionRunCallback
import androidx.glance.appwidget.state.updateAppWidgetState
import androidx.glance.layout.*
import androidx.glance.state.GlanceStateDefinition
import androidx.glance.state.PreferencesGlanceStateDefinition
import androidx.glance.text.Text
import androidx.glance.text.TextAlign
import androidx.glance.text.TextStyle
import androidx.glance.unit.ColorProvider
private val countPreferenceKey = intPreferencesKey("count-key")
private val countParamKey = ActionParameters.Key<Int>("count-key")
class CounterWidget : GlanceAppWidget(){
override val stateDefinition: GlanceStateDefinition<*> =
PreferencesGlanceStateDefinition
@Composable
override fun Content(){
val prefs = currentState<Preferences>()
val count = prefs[countPreferenceKey] ?: 0
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalAlignment = Alignment.CenterVertically,
modifier = GlanceModifier
.background(Color(0xFFD3E9FA))
.fillMaxSize()
) {
Text(
text = count.toString(),
modifier = GlanceModifier.fillMaxWidth(),
style = TextStyle(
textAlign = TextAlign.Center,
color = ColorProvider(Color.Blue),
fontSize = 50.sp
)
)
Spacer(modifier = GlanceModifier.padding(8.dp))
Button(
text = "Up",
modifier = GlanceModifier
.background(Color(0xFFB6C0C9))
.size(100.dp,50.dp),
onClick = actionRunCallback<UpdateActionCallback>(
parameters = actionParametersOf(
countParamKey to (count + 1)
)
)
)
}
}
}
class UpdateActionCallback : ActionCallback{
override suspend fun onRun(context: Context, glanceId: GlanceId,
parameters: ActionParameters) {
val count = requireNotNull(parameters[countParamKey])
updateAppWidgetState(
context = context,
definition = PreferencesGlanceStateDefinition,
glanceId = glanceId
){ preferences ->
preferences.toMutablePreferences()
.apply {
this[countPreferenceKey] = count
}
}
CounterWidget().update(context,glanceId)
}
}
class CounterWidgetReceiver : GlanceAppWidgetReceiver(){
override val glanceAppWidget:GlanceAppWidget = CounterWidget()
}
res/xml/counter_widget_info.xml
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/app_name"
android:minWidth="100dp"
android:minHeight="50dp"
android:resizeMode="horizontal|vertical"
android:targetCellWidth="3"
android:targetCellHeight="2"
android:widgetCategory="home_screen"
/>
AndroidManifest.xml [Part]
<receiver
android:name=".CounterWidgetReceiver"
android:enabled="@bool/glance_appwidget_available"
android:exported="false">
<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>
build.gradle [app] [dependencies]
implementation "androidx.glance:glance-appwidget:1.0.0-alpha03"
- jetpack compose - Kotlinx serialization build json array
- jetpack compose - Flow current time
- jetpack compose - How to flow a list
- jetpack compose - How to use ViewModel state
- jetpack compose - Flow using ViewModel
- jetpack compose - Search Room data using ViewModel
- jetpack compose - ViewModel Room add insert data
- jetpack compose - ViewModel Room edit update data
- jetpack compose - ViewModel Room delete clear data
- jetpack compose - Icon from vector resource
- jetpack compose - IconButton from vector resource