android - notifyappwidgetviewdatachanged 无法在我的小部件上的 ListView 上工作

标签 android listview widget android-appwidget

我尝试了很多解决方案,但几周后我无法解决这个问题:为什么“notifyappwidgetviewdatachanged”不起作用?如何更新放置在我的小部件上的 ListView ?我哪里错了?

这是我的课。

小部件提供者:

public class Widget_Provider extends AppWidgetProvider
{
public static final String ACTION_MOSTRAORARI = "fACTION_TOAST";
public static final String EXTRA_STRING = "EXTRA_STRING";

@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)
    {
        RemoteViews views = updateWidgetListView(context, appWidgetId);

        final Intent onItemClick = new Intent(context, Widget_Provider.class);
        onItemClick.setAction(ACTION_MOSTRAORARI);
        onItemClick.setData(Uri.parse(onItemClick.toUri(Intent.URI_INTENT_SCHEME)));
        final PendingIntent onClickPendingIntent = PendingIntent.getBroadcast(context, 0, onItemClick, PendingIntent.FLAG_UPDATE_CURRENT);
        views.setPendingIntentTemplate(R.id.myStopList, onClickPendingIntent);

        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
    super.onUpdate(context, appWidgetManager, appWidgetIds);
}

public RemoteViews updateWidgetListView(Context context, int appWidgetId)
{
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
    Intent svcIntent = new Intent(context, Widget_Service.class);
    svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
    remoteViews.setRemoteAdapter(R.id.myStopList, svcIntent);
    return remoteViews;
}

@Override
public void onReceive(Context context, Intent intent)
{
    if (intent.getAction().equals(ACTION_MOSTRAORARI)) {

        if (MainUtils.isNewtworkAvailable(context)) 
        {
            String item = intent.getExtras().getString(EXTRA_STRING);
            Intent intentOrari = new Intent(context, Diag_MostraOrari.class);
            intentOrari.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            context.startActivity(intentOrari);
        }
    }

    super.onReceive(context, intent);
}

@Override
public void onDeleted(Context context, int[] appWidgetIds) {}

@Override
public void onEnabled(Context context) {}

@Override
public void onDisabled(Context context) {}
}

小部件服务:
public class Widget_Service extends RemoteViewsService
{

@Override
public RemoteViewsFactory onGetViewFactory(Intent intent)
{
    Map<String, ArrayList<String>> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

    /* ---
    * Here i fetch data from a local db and store it on "map"
    */ ---

    return (new Widget_ListProvider(this.getApplicationContext(), intent, map));
}

}

列表提供者:
public class Widget_ListProvider implements RemoteViewsFactory
{
private Map<String, ArrayList<String>> map = new HashMap<>();
private ArrayList<ListItem_Widget> listItemList = new ArrayList<>();
private Context context = null;
private int appWidgetId;

public Widget_ListProvider(Context context, Intent intent, Map<String, ArrayList<String>> map) 
{
    this.map = map;
    this.context = context;
    appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);

    populateListItem();
}

//This function populate the arraylist "listItemList" by the data stored on "map"
private void populateListItem() { [...] }

@Override
public int getCount() {
    return listItemList.size();
}

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

@Override
public RemoteViews getViewAt(int position)
{
    final RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.listitem_widget);
    ListItem_Widget listItem = listItemList.get(position);
    remoteView.setTextViewText(R.id.heading, listItem.heading);
    remoteView.setTextViewText(R.id.content, listItem.content);

    final Intent fillInIntent = new Intent();
    fillInIntent.setAction(Widget.ACTION_MOSTRAORARI);
    final Bundle bundle = new Bundle();
    bundle.putString(Widget.EXTRA_STRING, listItem.heading);
    fillInIntent.putExtras(bundle);
    remoteView.setOnClickFillInIntent(R.id.listrow, fillInIntent);

    return remoteView;
}


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

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

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

@Override
public void onCreate() {}

@Override
public void onDataSetChanged() {}

@Override
public void onDestroy() {}

}

我的 ListView 自定义项的 xml 仅包含两个 TextView :“标题”和“内容”。

我哪里错了?为什么当我从另一个 Activity 中调用“notifyappwidgetviewdatachanged”时没有任何 react ?

[编辑]

这就是我需要更新我的小部件的 Activity 。
public class Diag_Line extends AppCompatActivity 
{
    //[...]

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        //[...]
        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
        ComponentName thisAppWidget = new ComponentName(getApplicationContext().getPackageName(), Widget.class.getName());
        int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
        appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.myStopList);

        //"myStopList" is the id of my listview inside the widget xml.

        //[...]
    }
}

最佳答案

好吧,问题很明显:在您的 RemoteViewsFactory 中,您有一个空方法 onDataSetChanged() .但是当你触发 notifyAppWidgetViewDataChanged() ,您将在 onDataSetChanged() 中收到回调.为了更好地理解,请查看此图片。
enter image description here

如果 Diag_Line 是配置 Activity ,只需执行以下操作:

 appWidgetManager.updateAppWidget(appWidgetIds, views); // views is a RemoteViews that you need to build
 appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.myStopList);

另请查看官方文档 here

更新
给你一些提示。如果您正在使用小部件,请在后台进行所有获取数据和填充 RemoteViews(IntentService 是一个不错的方法)。因此,只需在此处制作 IntentService 并为小部件制作逻辑。如果您通过广播触发更新,请不要忘记将他设为前台(仅适用于 Android O)。您也可以查看library这一切都适合你。

关于android - notifyappwidgetviewdatachanged 无法在我的小部件上的 ListView 上工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47369381/

相关文章:

android - 插入联系意向、多个电话/电子邮件/等类型?

android - 如何在 gingerbread 和更低版本的设备上运行 api 级别 14 演示

java - 从 Android 中的 Listview Adapter 访问 Activity 中的 TextView

android - 在清扫选项卡中插入 ListView

html - 通过向列表添加新的列表项来计算列表高度

android - 在 Canvas 上绘制的 View 上设置 onClickListener

android - 如何在 ExoPlayer 中显示图像?

javascript - 需要一个可以处理实时更新的可排序 JavaScript 表

widget - CodeMirror - addWidget 的用途是什么以及如何使用它?

android - 识别这个 Android Widget