【问题标题】:android appwidget listview not updatingandroid appwidget listview没有更新
【发布时间】:2016-11-16 00:48:48
【问题描述】:

我编写了一个 AppWidget,它在 ListView 中显示来自 ContentProvider 的一些数据,但我无法更新它。当我第一次创建小部件时,它会正确填充,但在 AlarmManager 的 PendingIntent 到达后,ListView 上不会发生更新。代码如下:

Intent update = new Intent(context, MenuWidgetProvider.class);
update.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
update.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pIUpdate = PendingIntent.getBroadcast(context, 0, update, 0);
((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).
set(AlarmManager.RTC, nextTime.toMillis(false), pIUpdate);

Log.d(TAG, "updating: " + dmt.mealName);

for (int i = 0; i < appWidgetIds.length; ++i) {
    int widgetId = appWidgetIds[i];

    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_menu);
    // meal name
    views.setTextViewText(R.id.widget_locname, prefs.getString(PREF_WIDGET_LOCNAME, ""));

    // adapter
    Intent adapter = new Intent(context, MenuWidgetAdapterService.class);
    adapter.putExtra(EXTRA_LOCATIONID, prefs.getInt(PREF_WIDGET_LOCID, -1));
    adapter.putExtra(EXTRA_MEALNAME, dmt.mealName);
    adapter.putExtra(EXTRA_DATE, dmt.date.toString());
    views.setRemoteAdapter(R.id.widget_list, adapter);

    // update
    manager.updateAppWidget(widgetId, views);
}

super.onUpdate(context, manager, appWidgetIds);

奇怪的是,当更新发生时,onUpdate() 方法运行——我看到了 Log.d 调用的输出——但是在我的 RemoteViewsFactory 中没有调用 onDataSetChanged()。即使我调用 notifyAppWidgetViewDataChanged,也没有效果。

【问题讨论】:

    标签: android listview widget android-appwidget


    【解决方案1】:

    这是因为您的 RemoteViewsFactory 缓存了它为每个小部件 ID 创建的工厂。因此,当同一个小部件(通过您的小部件适配器服务)发送创建新工厂的请求时,将返回同一个工厂。因此,列表视图没有“更新”。

    我是如何解决这个问题的:

    在您的 WidgetProviderClass 中

    adapter.setData(Uri.fromParts("content", String.valueOf(appWidgetIds[i]+randomNumber), null));
    

    其中 randomNumber 是一个随机数(您的 WidgetProvider 类的公共静态成员)。

    然后在你的 RemoteViewsFactory 类中,做:

    appWidgetId = Integer.valueOf(intent.getData().getSchemeSpecificPart())
                - WidgetProvider.randomNumber;
    

    这“愚弄”了服务,使其认为它必须为另一个小部件创建一个工厂,因此,使用更新的值创建一个新工厂,并将其附加到您的小部件。

    希望这会有所帮助。

    【讨论】:

    • 这种技术有效,但是当我对小部件进行内存分析时,内存消耗会增加。为了调试/分析目的,我每隔一分钟设置一个警报。
    • 这个问题把我逼疯了。你拯救了我的一天。您是如何找到这个解决方案的?只是好奇。谢谢普拉泰克。
    • 请问这个解决方案的成本是多少?
    • 你是javatar!
    • 这是一个巧妙的解决方法,但您真正需要做的只是致电widgetManager.notifyAppWidgetViewDataChanged(id, R.id.your_list)。这是更新集合视图的专用方法,不涉及黑客攻击
    【解决方案2】:

    试试动态号

    在您的 WidgetProviderClass 中:

    int randomNumber=(int)(Math.random()*1000); 
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId+randomNumber);
    
               intent.setData(Uri.fromParts("content", String.valueOf(appWidgetId), null));
    
               intent.putExtra("random",randomNumber );
               intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
               rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
    

    在你的 RemoteViewsFactory 类中,做:

    AppWidgetId = Integer.valueOf(intent.getData().getSchemeSpecificPart());
    

    【讨论】:

      【解决方案3】:

      即使我也有同样的问题。 小部件的RemoteView有这个问题。

      解决方案: 给自己发送广播并再次刷新列表。即将数据设置为您的完整视图,然后将广播发送给您自己。

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-09
        • 2011-10-20
        • 2015-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多