Android 带有ListView的小部件显示';装载';对于找到的每个项目

Android 带有ListView的小部件显示';装载';对于找到的每个项目,android,android-listview,android-widget,Android,Android Listview,Android Widget,我正试图为我的Android应用程序构建一个小部件,但我遇到了一个问题:虽然ListView确实找到了数据(通过调试器,我可以看到我的RemoteViewFactory实现中的getViewAt方法被调用并返回一个正确的RemoteView),但找到的每个条目在我的小部件中都显示为“正在加载…” 请注意:在我的数据库中确实找到了4个条目,getViewAt方法被调用了四次,每次都返回一个正确的列表项 我的代码基于,使用了作为技术参考的 在试图解决这个问题时,我咨询了stackoverflow并

我正试图为我的Android应用程序构建一个小部件,但我遇到了一个问题:虽然ListView确实找到了数据(通过调试器,我可以看到我的RemoteViewFactory实现中的getViewAt方法被调用并返回一个正确的RemoteView),但找到的每个条目在我的小部件中都显示为“正在加载…”

请注意:在我的数据库中确实找到了4个条目,getViewAt方法被调用了四次,每次都返回一个正确的列表项

我的代码基于,使用了作为技术参考的

在试图解决这个问题时,我咨询了stackoverflow并找到了一些。最常见的修复建议有:

  • 确保getViewTypeCount方法返回的值不是0(通常是1,因为大多数小部件只使用一种视图类型)
  • 确保只使用了一种方法
  • 一些更模糊的建议,例如一些任意视图属性应该或不应该使用
我已经尝试了上面所有的建议,并且只使用了支持的视图,但是我的项目仍然没有显示。这里有人有主意吗

我编写的相关代码列表:

添加到my AndroidManifest.xml文件的条目

    <service
        android:name=".widget.DfdWidgetService"
        android:permission="android.permission.BIND_REMOTEVIEWS" />

    <receiver android:name=".widget.DfdWidget">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>

        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/dfd_widget_info" />
    </receiver>
小部件服务类

public class DfdWidget extends AppWidgetProvider {

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
        Intent intent = new Intent(context, DfdWidgetService.class);

        RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.dfd_widget);
        remoteViews.setRemoteAdapter(R.id.widgetRemindersListView, intent);
        remoteViews.setEmptyView(R.id.widgetRemindersListView, R.id.widgetEmptyViewText);

        // Instruct the widget manager to update the widget
        appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
    }

    @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);
        }
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }

    @Override
    public void onEnabled(Context context) {
        super.onEnabled(context);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
    }

    @Override
    public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
        super.onRestored(context, oldWidgetIds, newWidgetIds);
    }
}
public class DfdWidgetService extends RemoteViewsService {
    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        return new DfdRemoteViewsFactory(getApplicationContext());
    }

    class DfdRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
        private final Context context;
        private ReminderRepository reminderRepository;
        private List<Reminder> reminders;

        public DfdRemoteViewsFactory(Context context) {
            this.context = context;
            this.reminderRepository = ReminderRepository.getReminderRepository(context);
        }

        @Override
        public void onCreate() {
            reminders = reminderRepository.getAllRemindersForTodayList();
        }

        @Override
        public void onDataSetChanged() {
            reminders = reminderRepository.getAllRemindersForTodayList();
        }

        @Override
        public void onDestroy() {
            reminders.clear();
        }

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

        @Override
        public RemoteViews getViewAt(int position) {
            Reminder reminder = reminders.get(position);
            RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.id.widgetListItem);

            remoteView.setTextViewText(R.id.widgetReminderName, reminder.getName());
            // Removed code that sets the other fields as I tried it with and without and it didn't matter. So removed for brevity

            return remoteView;
        }

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

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

        @Override
        public long getItemId(int position) {
            return reminders.get(position).getId();
        }

        @Override
        public boolean hasStableIds() {
            return true;
        }
    }
}
公共类DfdWidgetService扩展了RemoteViewsService{
@凌驾
公共远程视图工厂onGetViewFactory(意图){
返回新的DfdRemoteViewsFactory(getApplicationContext());
}
类DfdRemoteViewsFactory实现RemoteViewsService.RemoteViewsFactory{
私人最终语境;
私人催款催款催款催款催款催款催款催款催款催款;
私人名单提醒;
公共DfdRemoteViewsFactory(上下文){
this.context=上下文;
this.rementerrepository=rementerrepository.getrementerrepository(上下文);
}
@凌驾
public void onCreate(){
reminders=reminderRepository.getAllRemindersForTodayList();
}
@凌驾
公共无效onDataSetChanged(){
reminders=reminderRepository.getAllRemindersForTodayList();
}
@凌驾
公共空间{
提醒。清除();
}
@凌驾
public int getCount(){
返回提醒。大小();
}
@凌驾
公共远程视图getViewAt(内部位置){
提醒=提醒。获取(位置);
RemoteViews remoteView=新的remoteView(context.getPackageName(),R.id.widgetListItem);
remoteView.setTextViewText(R.id.widgetMemorinterName,remention.getName());
//删除了设置其他字段的代码,因为我尝试使用和不使用它们,但这并不重要。因此,为了简洁起见,删除了这些代码
返回远程视图;
}
@凌驾
公共远程视图getLoadingView(){
返回null;
}
@凌驾
public int getViewTypeCount(){
返回1;
}
@凌驾
公共长getItemId(int位置){
返回提醒。get(position.getId();
}
@凌驾
公共布尔表ID(){
返回true;
}
}
}
将布局资源ID作为第二个参数。您正在传递一个小部件ID


因此,将
R.id.widgetListItem
替换为
R.layout.whateyourlayoutnameisforthelistems
,其中用列表项的布局名称替换
whateyourlayoutnameisforthelistems

RemoteViews-remoteView=新的远程视图(context.getPackageName(),R.id.widgetListItem)
–在
getViewAt()
中,应该是
R.layout
,而不是
R.id
。可能只是一个输入错误,假设您将布局命名为相同的东西。另外,与当前问题无关,但是在布局中使用
app
名称空间前缀的任何内容在
remoteview
中都不起作用;e、 例如,
app:srcCompat
。仅供参考。事实上,你的评论一针见血!您和Commonware都很快找到了这个!我不知道你和迈克怎么这么快就找到了,但是干杯@Lynxian:正如您所指出的,正确的计数显示了您的
RemoteViewsService
正在被调用。对行布局XML的快速检查表明,“加载…”文本不是来自您的代码,这意味着小部件主机使用您的行有困难。这将问题限制在为行设置
remoteview
的位置,而这只是几行代码。
public class DfdWidget extends AppWidgetProvider {

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
        Intent intent = new Intent(context, DfdWidgetService.class);

        RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.dfd_widget);
        remoteViews.setRemoteAdapter(R.id.widgetRemindersListView, intent);
        remoteViews.setEmptyView(R.id.widgetRemindersListView, R.id.widgetEmptyViewText);

        // Instruct the widget manager to update the widget
        appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
    }

    @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);
        }
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }

    @Override
    public void onEnabled(Context context) {
        super.onEnabled(context);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
    }

    @Override
    public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
        super.onRestored(context, oldWidgetIds, newWidgetIds);
    }
}
public class DfdWidgetService extends RemoteViewsService {
    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        return new DfdRemoteViewsFactory(getApplicationContext());
    }

    class DfdRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
        private final Context context;
        private ReminderRepository reminderRepository;
        private List<Reminder> reminders;

        public DfdRemoteViewsFactory(Context context) {
            this.context = context;
            this.reminderRepository = ReminderRepository.getReminderRepository(context);
        }

        @Override
        public void onCreate() {
            reminders = reminderRepository.getAllRemindersForTodayList();
        }

        @Override
        public void onDataSetChanged() {
            reminders = reminderRepository.getAllRemindersForTodayList();
        }

        @Override
        public void onDestroy() {
            reminders.clear();
        }

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

        @Override
        public RemoteViews getViewAt(int position) {
            Reminder reminder = reminders.get(position);
            RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.id.widgetListItem);

            remoteView.setTextViewText(R.id.widgetReminderName, reminder.getName());
            // Removed code that sets the other fields as I tried it with and without and it didn't matter. So removed for brevity

            return remoteView;
        }

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

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

        @Override
        public long getItemId(int position) {
            return reminders.get(position).getId();
        }

        @Override
        public boolean hasStableIds() {
            return true;
        }
    }
}
RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.id.widgetListItem)