以下部分介绍如何更新 GlanceAppWidget
并管理其状态。
管理 GlanceAppWidget
状态
提供的 GlanceAppWidget
类在每次小部件创建或需要更新时都会实例化,因此它应该无状态且被动。
状态的概念可以分为以下几类
- 应用程序状态:应用的状态或内容,小部件需要这些状态或内容。例如,用户定义的存储目的地列表(即数据库)。
- Glance 状态:仅与应用小部件相关的特定状态,不一定修改或影响应用的状态。例如,在小部件中选中了一个复选框或增加了计数器。
使用应用程序状态
应用小部件应处于被动状态。每个应用程序负责管理数据层和处理状态,例如空闲、加载和错误,这些状态会反映在小部件 UI 中。
例如,以下代码从存储库层的内存缓存中检索目的地,提供存储的目的地列表,并根据其状态显示不同的 UI
class DestinationAppWidget : GlanceAppWidget() { // ... @Composable fun MyContent() { val repository = remember { DestinationsRepository.getInstance() } // Retrieve the cache data everytime the content is refreshed val destinations by repository.destinations.collectAsState(State.Loading) when (destinations) { is State.Loading -> { // show loading content } is State.Error -> { // show widget error content } is State.Completed -> { // show the list of destinations } } } }
每当状态或数据发生变化时,应用程序都负责通知并更新小部件。有关更多信息,请参阅 更新 GlanceAppWidget。
更新 GlanceAppWidget
如 管理 GlanceAppWidget
状态 部分所述,应用小部件托管在不同的进程中。Glance 将内容转换为实际的 RemoteViews
并将其发送到主机。要更新内容,Glance 必须重新创建 RemoteViews
并再次发送。
要发送更新,请调用 GlanceAppWidget
实例的 update
方法,并提供 context
和 glanceId
MyAppWidget().update(context, glanceId)
要获取 glanceId
,请查询 GlanceAppWidgetManager
val manager = GlanceAppWidgetManager(context) val widget = GlanceSizeModeWidget() val glanceIds = manager.getGlanceIds(widget.javaClass) glanceIds.forEach { glanceId -> widget.update(context, glanceId) }
或者,使用 GlanceAppWidget update
扩展之一
// Updates all placed instances of MyAppWidget MyAppWidget().updateAll(context) // Iterate over all placed instances of MyAppWidget and update if the state of // the instance matches the given predicate MyAppWidget().updateIf<State>(context) { state -> state == State.Completed }
这些方法可以从应用程序的任何部分调用。由于它们是 suspend
函数,因此建议在主线程范围之外启动它们。在以下示例中,它们在 CoroutineWorker
中启动
class DataSyncWorker( val context: Context, val params: WorkerParameters, ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { // Fetch data or do some work and then update all instance of your widget MyAppWidget().updateAll(context) return Result.success() } }
有关协程的更多详细信息,请参阅 Android 上的 Kotlin 协程。