我知道这个问题已经被问了很多次,但我从头到尾阅读了所有的文档和答案,都没有帮助到我。 说实话,每个答案都关于如何解决这个问题有不同的说法。
现在回到我的问题。 我想要从某个活动中更新小部件列表视图,并为此创建了WidgetProvider#sendUpdateBroadcastToAllWidgets()
方法,我会从该活动中调用此方法。
它最终会调用onUpdate()
,因此广播可以被正确接收。 但是视图没有得到刷新。
我还尝试调用AppWidgetManager#notifyAppWidgetViewDataChanged()
并在WidgetFactory#onDataSetChanged()
中刷新数据,但该方法从未被调用。
所以我猜这一切都无法工作,因为远程视图工厂已被缓存,但我不知道如何可靠地克服这个问题。 有什么想法吗?
那么关于上下文呢? 我总是必须提供一个上下文,但我并不在意使用哪个。 有关系吗?
谢谢
PROVIDER
public class WidgetProvider extends AppWidgetProvider {
public static void sendUpdateBroadcastToAllWidgets(Context context) {
int allWidgetIds[] = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, WidgetProvider.class));
Intent intent = new Intent(context, WidgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
context.sendBroadcast(intent);
}
@Override
public void onUpdate(Context context, AppWidgetManager widgetManager, int[] widgetIds) {
for (int id : widgetIds) {
updateWidget(context, widgetManager, id);
}
super.onUpdate(context, widgetManager, widgetIds);
}
@Override
public void onDeleted(Context context, int[] widgetIds) {
WidgetPreferences prefs = new WidgetPreferences(context);
for (int widgetId : widgetIds) {
prefs.getWidgetPreferences(widgetId).edit().clear().commit();
}
super.onDeleted(context, widgetIds);
}
private static void updateWidget(Context context, AppWidgetManager widgetManager, int widgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
// set list adapter
Intent serviceIntent = new Intent(context, WidgetService.class);
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)));
views.setRemoteAdapter(android.R.id.list, serviceIntent);
views.setEmptyView(android.R.id.list, android.R.id.empty);
// set widget title
WidgetDataCategory category = new WidgetPreferences(context).getSavedCategory(widgetId);
views.setTextViewText(R.id.titleText, context.getString(category.titleResourceId()));
// set onclick listener - we create a pending intent template and when an items is clicked
// the intent is filled with missing data and sent
Intent startActivityIntent = new Intent(context, SimplePersonDetailActivity.class);
startActivityIntent.setData(Uri.parse(startActivityIntent.toUri(Intent.URI_INTENT_SCHEME)));
startActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivityIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, startActivityIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setPendingIntentTemplate(android.R.id.list, pendingIntent);
// all hail to Google
widgetManager.updateAppWidget(widgetId, views);
}
}
工厂
public class WidgetFactory implements RemoteViewsService.RemoteViewsFactory {
private Context context;
private List<Person> people = new ArrayList<>();
public WidgetFactory(Context context, Intent intent) {
this.context = context;
int widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
WidgetPreferences prefs = new WidgetPreferences(context);
WidgetDataCategory category = prefs.getSavedCategory(widgetId);
int numberOfItemsToShow = prefs.getSavedLimit(widgetId);
people = category.filterAndSlice(new PersonDao(context).getAllForGroup(Constants.SIMPLE_GROUP_ID), numberOfItemsToShow);
}
}
@Override
public void onCreate() {}
@Override
public void onDataSetChanged() {}
@Override
public void onDestroy() {}
@Override
public int getCount() {
return people.size();
}
@Override
public RemoteViews getViewAt(int position) {
Person person = people.get(position);
BigDecimal amount = ListViewUtil.sumTransactions(new TransactionDao(context).getAllForPerson(person));
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.item_widget);
remoteViews.setTextViewText(R.id.nameText, person.getName());
remoteViews.setTextViewText(R.id.amountText, MoneyFormatter.withoutPlusPrefix().format(amount));
// fill details for the onclick listener (updating the pending intent template
// set in the WidgetProvider)
Intent listenerIntent = new Intent();
listenerIntent.putExtra(Constants.PERSON_ID, people.get(position).getId());
remoteViews.setOnClickFillInIntent(R.id.widgetItem, listenerIntent);
return remoteViews;
}
@Override
public RemoteViews getLoadingView() {
return null;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public boolean hasStableIds() {
return true;
}
}
updateWidget()
或者通常在onUpdate()
中的代码。 - user219882