我正在为我正在开发的一个简单的待办事项列表应用程序实现我的第一个 Jetpack Glance 支持的应用程序小部件。我按照https://developer.android.com/jetpack/compose/glance上的指南进行操作,一切都很好,直到我需要更新我的小部件以匹配应用程序内发生的数据更新。
根据我对管理和更新 GlanceAppWidget的理解,可以通过从应用程序代码本身调用小部件实例上的update
、updateIf
或方法来触发小部件重组。updateAll
具体来说,对这些函数的调用应该触发该GlanceAppWidget.provideGlance(context: Context, id: GlanceId)
方法,该方法负责获取任何所需的数据并提供小部件内容,如以下代码片段中所述:
class MyAppWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {
// In this method, load data needed to render the AppWidget.
// Use `withContext` to switch to another thread for long running
// operations.
provideContent {
// create your AppWidget here
Text("Hello World")
}
}
}
Run Code Online (Sandbox Code Playgroud)
但就我而言,它并不总是有效。以下是我在几次尝试后观察到的结果:
updateAll
)。小部件已更新并显示最新数据,provideGlance
方法根本不会被触发。然后我查看了GlanceAppWidget …
我不确定这是否是 Glance 仍处于 alpha 版本时出现的问题,或者我是否做错了什么。但每次onUpdate()
触发小部件接收器时,它都会被完全重新组合。它重置为initialLayout
一秒钟,然后重新组合到正确的状态。
问题是,即使小部件状态没有变化,它也会发生,所以每次小部件更新时它都会像这样“闪烁”,看起来非常糟糕。
我已经使用 实现了手动更新MyWidget().updateIf<Preferences>
,以便我的应用程序仅在状态更改时更新小部件,但操作系统仍在执行自动更新,因此“闪烁”仍在发生。
编辑:
经过更多测试,我发现调用该GlanceAppWidget
update()
方法时实际上并没有发生这种情况。事实上,我删除了对我的应用程序的所有GlanceAppWidget
调用GlanceAppWidgetManager
。但是,每当小部件更新(由操作系统自动触发)时,“闪烁”仍然会发生。
我尝试通过将 设为 0 和 86400000 来禁用 XML 中的小部件刷新updatePeriodMillis
,但这似乎不起作用。updatePeriodMillis
我也尝试过从 XML 中删除。
因此,似乎只要 GlanceAppWidget 调用其 Content() 函数,就会发生闪烁,无论实际触发该调用的是什么。仅供参考,下面是该小部件的基本 Kotlin 类:
class WidgetSimple : GlanceAppWidget() {
override val sizeMode: SizeMode = SizeMode.Single
@Composable
override fun Content() {
// code to actually draw the components
// no matter what's here, the widget will flicker …
Run Code Online (Sandbox Code Playgroud) 我有一个使用 Jetpack Compose 和 Jetpack Glance 库开发的小部件,该小部件是一个 LazyColumn 列表,我在向 Room Database 数据库进行查询后在其中传递信息。
为了尝试加载图像,我将Image()与提供程序一起使用,并向其传递一个字符串(这是我要加载的图像的 url)
Image(
modifier = GlanceModifier.size(50.dp),
provider = ImageProvider(item.image),
contentDescription = null
)
Run Code Online (Sandbox Code Playgroud)
这没有加载图像,我尝试将该图像 url 传递给位图,以使用 BitmapImageProvider() 加载它,但它不起作用。有没有办法使用 Jetpack Glance 将远程图像加载到小部件?
我有一个表,其中包含用户创建的所有小部件。我想使用相应的表条目自定义各个小部件,并在与小部件交互时更新相应的表条目。
uid | 应用程序小部件ID | 标题 |
---|---|---|
0 | 23 | 第一个小部件 |
1 | 165 | 第二个小部件 |
(1) 当用户单击小部件时,我只想更新被单击的小部件的条目。在非 Glance 世界中,我通过向每个小部件添加一个 onClickListener 来实现此目的,如下所示:
val widgetView = RemoteViews(context.packageName, R.layout.widget_layout)
val widgetPendingIntent = ...
widgetView.setOnClickPendingIntent(R.id.appwidget_text, widgetPendingIntent)
val appWidgetManager = AppWidgetManager.getInstance(context)
appWidgetManager.updateAppWidget(appWidgetId, widgetView)
Run Code Online (Sandbox Code Playgroud)
在概览小部件中,我假设我需要使可组合项可单击,如下所示:
@Composable
override fun Content() {
Column(
modifier = GlanceModifier
.fillMaxSize()
.clickable(onClick = actionRunCallback<ClickOnWidget>())
) {
Text(
text = "Title",
modifier = GlanceModifier.fillMaxSize(),
)
}
}
Run Code Online (Sandbox Code Playgroud)
ActionCallback 看起来像这样:
class ClickOnWidget : ActionCallback {
override suspend fun onRun(context: Context, glanceId: GlanceId, parameters: ActionParameters) {
// Update my table …
Run Code Online (Sandbox Code Playgroud) android android-widget android-jetpack-compose glance glance-appwidget
我最新的想法是使用
updateAppWidgetState(context = context, definition = PreferencesGlanceStateDefinition, glanceId = glanceId) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
和
GlanceWidget().update(context = context, glanceId = glanceId)
Run Code Online (Sandbox Code Playgroud)
但我无权访问glanceId。
问题的背景是我想将 uid 添加到 AppWidgetState,如本问题所述:How to get the AppWidgetId of a Compose Glance widget?
我怎样才能获得glanceId(例如,从我在配置活动中有权访问的appWidgetId)或者我该如何实现这一点?
android-widget android-jetpack-compose glance glance-appwidget