在Widget中更新Android ListView

时间:2012-08-07 18:32:33

标签: android listview service widget

当我尝试更新内容时,我的App-Widget出现问题。

小部件如下所示: http://i.stack.imgur.com/tEGLv.jpg

Widget包含一个Header(Buttons + TextViews)和一个ListView。 如果用户按下按钮,ListView会显示第二天的内容,一切正常。但问题是,如果我尝试从我的应用程序更新窗口小部件或自动更新时间段ListView doenst更新。

这是我的代码。

的AppWidgetProvider:

public class StudyWidgetProvider extends AppWidgetProvider{

private static String BUTTON_BACK = "BUTTON_BACK";
private static String BUTTON_FORWARD = "BUTTON_FORWARD";

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {  
    context.startService(new Intent(context, UpdateService.class));
}

@Override
public void onReceive(Context context, Intent intent) {
    super.onReceive(context, intent);
    if(WidgetViewsFactory.currentDate == null){
        WidgetViewsFactory.currentDate = Calendar.getInstance();
    }

    String action = intent.getAction();
    if(action != null){
        if(action.equals(BUTTON_BACK)){
            WidgetViewsFactory.currentDate.add(Calendar.DATE, -1);
        }
        if(action.equals(BUTTON_FORWARD)){
            WidgetViewsFactory.currentDate.add(Calendar.DATE, 1);
        }
    }

    context.startService(new Intent(context, UpdateService.class));
}   
 }

UpdateService,用于处理Widget的更新。

    @Override
@Deprecated
public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
    Log.i(LOG_TAG, "Update-Service started");

    RemoteViews widget = buildUpdate(this);
    ComponentName thisWidget = new ComponentName(this, StudyWidgetProvider.class);
    AppWidgetManager manager = AppWidgetManager.getInstance(this);

    manager.notifyAppWidgetViewDataChanged(manager.getAppWidgetIds(thisWidget), R.id.words);
    manager.updateAppWidget(thisWidget, widget);

    Log.i(LOG_TAG, "The Content!");
    if(widgetObjects == null){
        Log.i(LOG_TAG, "WidgetObjects sind NULL");
    } else {
        Log.i(LOG_TAG, "WidgetObjects sind NICHT-NULL");

        for(int i=0; i<widgetObjects.size(); i++){
            Log.i(LOG_TAG, "--- " + widgetObjects.get(i).getName());
        }
    }

    Log.i(LOG_TAG, "Update-Service ended");
}


public RemoteViews buildUpdate(Context context){
    RemoteViews retVal = new RemoteViews(context.getPackageName(), R.layout.widget);

    if(WidgetViewsFactory.currentDate == null){
        WidgetViewsFactory.currentDate = Calendar.getInstance();
    }

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    ComponentName thisAppWidget = new ComponentName(context.getPackageName(), StudyWidgetProvider.class.getName());
    int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);

    loadSDCardContent(context, appWidgetManager, appWidgetIds);

    //Setzen des Widget-UIs
    Intent intent = new Intent(context, WidgetService.class);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds);
    intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));

    retVal.setRemoteAdapter(R.id.words, intent);

    SimpleDateFormat dateFormater = new SimpleDateFormat("EEEE");
    retVal.setTextViewText(R.id.widget_day, dateFormater.format(WidgetViewsFactory.currentDate.getTime()));
    dateFormater = new SimpleDateFormat("dd.MM.yyyy");
    retVal.setTextViewText(R.id.widget_date, dateFormater.format(WidgetViewsFactory.currentDate.getTime()));

    //Button-Actions
    Intent backIntent = new Intent(context, StudyWidgetProvider.class);
    backIntent.setAction(BUTTON_BACK);
    Intent forwardIntent = new Intent(context, StudyWidgetProvider.class);
    forwardIntent.setAction(BUTTON_FORWARD);
    PendingIntent backPendingIntent = PendingIntent.getBroadcast(context, 0, backIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    PendingIntent forwardPendingIntent = PendingIntent.getBroadcast(context, 0, forwardIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    retVal.setOnClickPendingIntent(R.id.widget_but_back, backPendingIntent);
    retVal.setOnClickPendingIntent(R.id.widget_but_forward, forwardPendingIntent);

    Intent clickIntent = new Intent(context, WidgetActivity.class);
    PendingIntent clickPI=PendingIntent.getActivity(context, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    retVal.setPendingIntentTemplate(R.id.words, clickPI);

    return retVal;
}

以下是我如何从我的应用程序更新小部件:

public RemoteViews buildUpdate(Context context){
    RemoteViews retVal = new RemoteViews(context.getPackageName(), R.layout.widget);

    if(WidgetViewsFactory.currentDate == null){
        WidgetViewsFactory.currentDate = Calendar.getInstance();
    }

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    ComponentName thisAppWidget = new ComponentName(context.getPackageName(), StudyWidgetProvider.class.getName());
    int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);

    loadSDCardContent(context, appWidgetManager, appWidgetIds);

    //Setzen des Widget-UIs
    Intent intent = new Intent(context, WidgetService.class);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds);
    intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));

    retVal.setRemoteAdapter(R.id.words, intent);

    SimpleDateFormat dateFormater = new SimpleDateFormat("EEEE");
    retVal.setTextViewText(R.id.widget_day, dateFormater.format(WidgetViewsFactory.currentDate.getTime()));
    dateFormater = new SimpleDateFormat("dd.MM.yyyy");
    retVal.setTextViewText(R.id.widget_date, dateFormater.format(WidgetViewsFactory.currentDate.getTime()));

    //Button-Actions
    Intent backIntent = new Intent(context, StudyWidgetProvider.class);
    backIntent.setAction(BUTTON_BACK);
    Intent forwardIntent = new Intent(context, StudyWidgetProvider.class);
    forwardIntent.setAction(BUTTON_FORWARD);
    PendingIntent backPendingIntent = PendingIntent.getBroadcast(context, 0, backIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    PendingIntent forwardPendingIntent = PendingIntent.getBroadcast(context, 0, forwardIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    retVal.setOnClickPendingIntent(R.id.widget_but_back, backPendingIntent);
    retVal.setOnClickPendingIntent(R.id.widget_but_forward, forwardPendingIntent);

    Intent clickIntent = new Intent(context, WidgetActivity.class);
    PendingIntent clickPI=PendingIntent.getActivity(context, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    retVal.setPendingIntentTemplate(R.id.words, clickPI);

    return retVal;
}

奇怪的是,当我按下小部件的按钮时,每个人都按照我的意愿工作。我的listview的onDatasetChanged方法被调用,内容正在改变,但如果我从我的应用程序尝试这个没有任何反应

我希望你们中的某个人知道为什么这不起作用。 我现在坚持了2天,我一点都不知道......

感谢您的帮助!

修改 我发现这不适用于我的设备(htc与miui v4),但在模拟器上。

编辑2 我在我的设备上安装了Android 4(带有Sense 4),之后它也运行了。看起来MIUI就是问题所在。

3 个答案:

答案 0 :(得分:6)

我将要解决这个问题,因为我遇到了同样的问题并找到了解决方案。

              manager.notifyAppWidgetViewDataChanged

这将在RemoteViewsFactory中发送对onDataSetChanged()的调用。添加一个调用以在该方法中构建您的视图。这解决了我所有的问题。

答案 1 :(得分:1)

仅通过广播与Widget通信。不要像这样直接调用它。如果需要,请使用粘性广播。

答案 2 :(得分:0)

这有效

<table class="my-table">
 <tr>
    <td>x</td>
    <td>1</td>
    <td>2</td>
    <td>3</td>
 </tr>
 <tr>
    <td>f(x)</td>
    <td>1</td>
    <td>4</td>
    <td>9</td>
 </tr>
</table>