列表未更新的应用小部件-为什么这样做?

时间:2019-06-29 03:55:47

标签: java android android-widget

我有一个小部件,在列表视图中包含两个文本(目的是允许长文本滚动)。当应用程序运行时,当我单击小部件中的“刷新小部件”按钮时,它开始工作。但是,当应用程序未运行时,将在不更新列表视图的同时更新小部件的标题。

这是我的代码

MyAppWidget.java

public class MyAppWidget extends AppWidgetProvider {
  private static final String RELOAD_CLICKED = "MyAppWidget#btnReload";

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // There may be multiple widgets active, so update all of them
        for (int appWidgetId : appWidgetIds) {
            updateAppWidget(context, appWidgetManager, appWidgetId, getClass());
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
        if (RELOAD_CLICKED.equals(intent.getAction())) {
            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
            int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                    AppWidgetManager.INVALID_APPWIDGET_ID);
            updateAppWidget(context, appWidgetManager, appWidgetId, getClass());
        } 
    }


    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                                int appWidgetId, Class<?> cls) {

        WidgetViewModel viewModel = DbManager.getInstance(context).getRandomWidget();

        // Construct the RemoteViews object
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_app_widget);
        views.setTextViewText(R.id.txtTitle, viewModel.title);
        Intent intent = new Intent(context, WidgetService.class);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
        String texts[] = new String[] {viewModel.widgetText1, widgetText2};
        intent.putExtra("texts", texts);
        views.setRemoteAdapter(R.id.widgetListTexts, intent);
        views.setOnClickPendingIntent(R.id.btnReload,
                getPendingSelfIntent(context, RELOAD_CLICKED, appWidgetId, cls));
        // Instruct the widget manager to update the widget
        appWidgetManager.updateAppWidget(appWidgetId, views);

        Intent updateIntent = new Intent(WidgetRemoteViewsFactory.UPDATE_WIDGET_ACTION);
        updateIntent.putExtra("texts", texts);
        context.sendBroadcast(updateIntent);
    }

    private static PendingIntent getPendingSelfIntent(Context context, String action,
                                                      int appWidgetId, Class<?> cls) {
        Intent intent = new Intent(context, cls);
        intent.setAction(action);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        return PendingIntent.getBroadcast(context, 0, intent, 0);
    }
}

WidgetRemoteViewsFactory.java

public class WidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {

    public static final String UPDATE_WIDGET_ACTION = "WidgetRemoteViewsFactory#update";

    private final Context context;
    private final int appWidgetId;

    private String[] texts;
    private BroadcastReceiver receiver;

    public WidgetRemoteViewsFactory(Context context, Intent intent) {
        this.context = context;
        texts = intent.getStringArrayExtra("texts");
        appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);

        context.registerReceiver(receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                texts = intent.getStringArrayExtra("texts");
                AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widgetListTexts);
            }
        }, new IntentFilter(UPDATE_WIDGET_ACTION));
    }

    @Override
    public int getCount() {
        return 2;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public RemoteViews getLoadingView() {
        return null;
    }

    @Override
    public RemoteViews getViewAt(int position) {
        RemoteViews remoteView = new RemoteViews(context.getPackageName(),
                position == 0 ?
                        R.layout.app_widget_textview1
                        : R.layout.app_widget_textview2);

        remoteView.setTextViewText(
                position == 0 ?
                        R.id.widgetText1
                        : R.id.widgetText2,
                texts[position]);

        return remoteView;
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public void onCreate() {
    }

    @Override
    public void onDataSetChanged() {
    }

    @Override
    public void onDestroy() {
        context.unregisterReceiver(receiver);
    }
}

和WidgetService.java:

public class WidgetService extends RemoteViewsService {

    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        return new WidgetRemoteViewsFactory(this.getApplicationContext(), intent);
    }
}

1 个答案:

答案 0 :(得分:0)

通过删除广播并仅将最后一个数据集保存在updateAppWidget()中,然后在调用appWidgetManager.updateAppWidget后也调用appWidgetManager.notifyAppWidgetViewDataChanged来更新列表来进行修复。在工厂中,只需加载文件中的最后一个数据集即可。