我正在构建一个小部件来加载每个食谱的成分列表.我的目标是能够拥有多个小部件实例并独立加载/更新它们的成分列表(ListView).我已经为用户设置了一个配置活动来选择配方.在配置和填充 remoteViews 并为我的成分列表制作 RemoteAdapter 之后,该方法将始终调用:
I'm building a widget to load a list of ingredients per recipe. My goal is to be able to have multiple instances of the widget and have their ingredient-list (ListView) loaded/updated independently. I've setup a configuration activity for user to select the recipe. After configuration and populating the remoteViews and making the RemoteAdapter for my list of ingredients, the method would always call:
appWidgetManager.updateAppWidget(mAppWidgetId, views);
appWidgetManager.notifyAppWidgetViewDataChanged(mAppWidgetId, R.id.widget_list_view_layout);
updateAppWidget 很好地更新了非集合视图,但是,我对我的集合视图(成分列表)的 notifyAppWidgetViewDataChanged() 感到不满.
updateAppWidget updates the non-collection views nicely, however, I'm having a beef with notifyAppWidgetViewDataChanged() for my collection view, the list of ingredients.
我第一次将小部件添加到屏幕(recipeId 4)时,它会正确加载并调用正确的服务和视图工厂来填充远程 listView.但如果我添加第二个,会发生以下情况(或缺少):
The first time I add the widget to the screen (recipeId 4), it loads correctly and calls the correct service and view factory to populate the remote listView. But if I add the second one, here is what happens (or lack thereof):
D/WidgetUtils: createAppWidgetResult() with appWidgetId: 78, recipeId: 4
D/WidgetUtils: RecipeId of the ingredients passed: 4
D/WidgetRemoteViewService: onGetViewFactory() call received with mRecipeId 4
D/WidgetRemoteViewsFactory: WidgetRemoteViewsFactory() constructed with recipeId: 4
D/WidgetRemoteViewsFactory: onDataSetChanged() called
D/WidgetUtils: createAppWidgetResult() with appWidgetId: 79, recipeId: 1
D/WidgetUtils: RecipeId of the ingredients passed: 1
D/WidgetUtils: createAppWidgetResult() with appWidgetId: 80, recipeId: 2
D/WidgetUtils: RecipeId of the ingredients passed: 2
日志结束
如果配方 ID 为 1
I was expecting the following, if the recipe id is 1
D/WidgetRemoteViewService: onGetViewFactory() call received with mRecipeId **1**
D/WidgetRemoteViewsFactory: WidgetRemoteViewsFactory() constructed with recipeId: **1**
D/WidgetRemoteViewsFactory: onDataSetChanged() called
但正如您从上面的日志中看到的那样,在 1 之后什么也没有发生(与 4 不同,这是预期的行为)
But as you can see from the above Log, nothing happens after 1 (unlike with 4 which is the expected behavior)
UI 方面,任何随后创建的小部件的列表视图实际上都包含配方 4(不是 1)的成分,即使配置活动清楚地将 id 传递为 1...2...6..etc.
UI wise, any subsequently created widget's listview actually has the ingredients for the recipe 4 (not 1), even when the configuration activity clearly passes the id as 1...2...6..etc.
奇怪的是:只有在我从主屏幕上删除所有小部件,然后添加一个小部件,例如配方 id 1 之后,它的 onDataSetChanged() 才会被调用?!,然后再一次,任何后续的小部件都不会被调用.
Strangely Enough: Only After I remove all my widgets from the home screen, and then add ONE widget, for example recipe id 1, then its onDataSetChanged() would be called?!, and again, any subsequent widget's won't be called.
查看屏幕截图 Nutella Pie Recipe 的 id 为 4,Brownies 食谱的 id 为 1. Nutella Pie 小部件首先添加,Nutella Pie 的成分已正确加载.布朗尼是第二个添加的,如您所见,成分是从第一个继承的,而且它们是不正确的.
See the screenshot The Nutella Pie Recipe's id is 4, and the Brownies Recipe's id is 1. The Nutella Pie widget is added first, the ingredients for the Nutella Pie is correctly loaded. The Brownies, is added second, and as you can see, the ingredients are carried over from the first one, and they are incorrect.
在模拟器和真实设备上测试 > API 21,结果相同.
Tested on emulator and real devices > API 21, same outcome.
在这里找到了@Joe 的答案 onGetViewFactory 只为多个小部件调用一次
Found the answer here by @Joe onGetViewFactory only called once for multiple widgets
事实证明,这与 RemoteViewService 如何处理意图有关.我正在创建 RemoteViewService 意图,就像我 99.999% 通常在任何活动中所做的那样,例如:
As it turns out, it is something about how RemoteViewService intent handling. I was creating the RemoteViewService intent like what I 99.999% normally do in any activity, ex:
// Create intent to start the service and to act as the remote listView adapter
Intent remoteViewIntent = new Intent(context, WidgetRemoteViewService.class);
remoteViewIntent.putExtra(EXTRA_RECIPE_ID, recipeId);
views.setRemoteAdapter(R.id.widget_recipe_ingredients_list, remoteViewIntent);
解决方案:代替
remoteViewIntent.putExtra(EXTRA_RECIPE_ID, recipeId);
改成:
remoteViewIntent.setData(Uri.fromParts("content", String.valueOf(recipeId), null));
在 RemoteViewsService 的 onGetViewFactory() 中,从 Intent 中获取数据,如下所示:
and in the RemoteViewsService's onGetViewFactory(), get the data from the intent like so:
long mRecipeId = Long.valueOf(intent.getData().getSchemeSpecificPart());
这篇关于每个 notifyAppWidgetViewDataChanged() 仅调用一次 RemoteViewFactory onDataSetChanged()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!