我有一个应用程序,其中有一个显示列表视图的小部件,我想根据用户在应用程序中打开的食谱更新列表。我想根据用户在应用程序中打开的食谱来更新列表。
要做到这一点,首先我发送了一个广播,当活动被打开时,有一个额外的整数。
然后在widget provider中,我用一个包含从广播中接收到的整数的意图来设置远程适配器。
现在我希望每次都能创建新的RemoteViewsFactory,这样我就可以从意图中提取一个整数,并根据这个数字加载不同的列表。
问题是这种情况只发生在应用程序第一次打开的时候,每隔一段时间只有MyWidgetRemoteViewsFactory中的onDataSetChanged()被调用,所以我无法获得配方号来正确更新数据。小组件中的列表从来没有得到更新。
如何强制widget重新创建RemoteViewsFactory?根据stackoverflow上的其他主题,我已经尝试在appWidgetManager.updateAppWidget(appWidgetId1, null)中传递null - 这没有工作。
MainListActivity.java - 发送广播
@Override
public void onItemClickListener(int itemID) {
Intent recipeIntent = new Intent(this, BakingWidgetProvider.class);
recipeIntent.setAction(BakingWidgetProvider.UPDATE_WIDGET_RECIPE);
recipeIntent.putExtra(StepsListActivity.EXTRA_RECIPE_ID, itemID);
sendBroadcast(recipeIntent);
Intent intent = new Intent(MainListActivity.this, StepsListActivity.class);
intent.putExtra(StepsListActivity.EXTRA_RECIPE_ID, itemID);
startActivity(intent);
}
BakingWidgetProvider.java - 接收广播。
@Override
public void onReceive(Context context, Intent intent) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
if (intent.getAction().equals(UPDATE_WIDGET_RECIPE)) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.baking_widget);
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
int viewIndex = intent.getIntExtra(StepsListActivity.EXTRA_RECIPE_ID, 0);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, BakingWidgetProvider.class));
for (int appWidgetId1 : appWidgetIds) {
//trying to pass null to clear the data ?
appWidgetManager.updateAppWidget(appWidgetId1, null);
}
Intent intent2 = new Intent(context, MyWidgetRemoteViewsService.class);
Bundle bundle = new Bundle();
bundle.putInt(StepsListActivity.EXTRA_RECIPE_ID,viewIndex );
intent2.putExtras(bundle);
remoteViews.setRemoteAdapter(R.id.list_view, intent2);
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.list_view);
//empty view
remoteViews.setEmptyView(R.id.list_view, R.id.empty_view);
for (int appWidgetId1 : appWidgetIds) {
appWidgetManager.updateAppWidget(appWidgetId1, remoteViews);
}
}
super.onReceive(context, intent);
}
MyWidgetRemoteViewsService.java - 从一个意图中获取一个整数来正确更新数据。
public class MyWidgetRemoteViewsService extends RemoteViewsService {
private static final String MyOnClick = "myOnClickTag";
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return new MyWidgetRemoteViewsFactory(this.getApplicationContext(), intent);
}
class MyWidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
List<Recipe> recipeList;
private Context mContext;
private int mRecipeOpen;
public MyWidgetRemoteViewsFactory(Context context, Intent intent) {
mRecipeOpen = intent.getExtras().getInt(StepsListActivity.EXTRA_RECIPE_ID);
mContext = context;
}
@Override
public void onCreate() {
}
@Override
public void onDataSetChanged() {
recipeList = AppDatabase.getInstance(getApplicationContext()).recipeDao().getAll();
}
@Override
public void onDestroy() {
}
@Override
public int getCount() {
return recipeList.get(mRecipeOpen).ingredients.size();
}
@Override
public RemoteViews getViewAt(int position) {
RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_list_item);
rv.setTextViewText(R.id.quantity, recipeList.get(mRecipeOpen).ingredients.get(position).getQuantity());
rv.setTextViewText(R.id.measurement, recipeList.get(mRecipeOpen).ingredients.get(position).getMeasure());
rv.setTextViewText(R.id.ingredient, recipeList.get(mRecipeOpen).ingredients.get(position).getIngredient());
return rv;
}
@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;
}
}
}
最后,我不得不改变我的方法。
我把MyWidgetRemoteViewsFactory放在一个单独的类中,并扩展了BroadcastReceiver。在这里的onReceive方法中,我可以用所需的整数来检索从BakingWidgetProvider发送的广播。