花花公子,
我的Android小部件只显示我的数据库中的一条记录。我确信从数据库中检索了多个项目。
WidgetProvider的onUpdate方法:
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
if (items == null) {
items = new ItemsData(new DbHelper(context));
}
final int N = appWidgetIds.length;
Item[] iii = items.getItemsArray();
Log.d(TAG, "got " + iii.length + " items from db");
ComponentName thisWidget = new ComponentName(context, WidgetProvider.class);
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
Log.d(TAG, "updating widget " + appWidgetId);
RemoteViews rv = new RemoteViews(context.getPackageName(),
R.layout.widgetlayout);
for (Item item : iii) {
Log.d(TAG, "updating item " + item.id + ", " + item.title);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.row);
views.setTextViewText(R.id.textViewShortName, item.title);
views.setTextViewText(R.id.textViewDesc, item.description);
views.setTextViewText(R.id.textViewDue, new StringBuilder()
.append(item.dueDate).toString());
rv.addView(R.id.llWidget, views);
}
appWidgetManager.updateAppWidget(thisWidget, rv);
}
}
我的布局只是:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/llWidget"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ff99ff">
<include
android:id="@+id/row"
layout="@layout/row" />
</LinearLayout>
'row'是三个TextView项目,根据我的需要排列。
这会发生什么:当我向db和widget更新添加项目时,只有最后一项 看得见。它位于顶部。
我已经搜索过android小部件指南,堆栈溢出,其他一些网站,一本书的教程,但即使有些人提供了类似的例子,我也无法让它工作...... 谷歌Android小部件指南显示了如何使用集合,但它仅适用于3.0+。 学习Android书籍描述了一个小部件,其元素被添加为行,所以我遵循它 - 但无法取得任何进展...... 人们询问从小部件中获取db的数据(例如Android: get Widget Data from database),据我所知,没有遇到过这样的问题。他们的解决方案对我不起作用。
现在我甚至不知道如何寻找错误...... 奇怪的是,在LogCat中我可以看到“更新项目X”行。
有什么想法吗?
更新1。 在Sergey Benner的信息之后更新了方法(相关部分):
Item[] iii = items.getItemsArray();
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
RemoteViews rv = new RemoteViews(context.getPackageName(),
R.layout.widgetlayout);
for (Item item : iii) {
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.row);
views.setTextViewText(R.id.textViewShortName, item.title);
views.setTextViewText(R.id.textViewDesc, item.description);
views.setTextViewText(R.id.textViewDue, new StringBuilder()
.append(item.dueDate).toString());
rv.addView(R.id.llWidget, views);
}
appWidgetManager.updateAppWidget(appWidgetId, rv);
}
更新2。
AndroidManifest文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.whatnot.todoex"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:debuggable="true"
android:name=".ToDoExApp" >
<activity
android:label="@string/app_name"
android:name=".ListItemsActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:label="@string/titleAdd" android:name=".AddItemActivity" />
<activity android:label="@string/titleRemindments" android:name=".RemindmentListActivity" />
<activity android:label="@string/titleAddRemindment" android:name=".AddRemindmentActivity" />
<activity android:label="@string/titleSetDate" android:name=".ChooseDateActivity" />
<receiver android:name=".WidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/widgetprovider" />
</receiver>
</application>
</manifest>
widgetprovider.xml:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="294dp"
android:minHeight="160dp"
android:updatePeriodMillis="3000"
android:initialLayout="@layout/widgetlayout" >
</appwidget-provider>
row.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textViewShortName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textViewDesc"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="0.80"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/textViewDue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>
并在本文开头更新了onUpdate方法。 WidgetProvider中没有其他东西:一个空的构造函数,onEnabled只有super.onEnabled .. 另外:我已经整个小部件布局和行xmls。
更新3。 现在,每次更改项目时,我都会运行以下方法:
private void updateWidget(Item item) {
Log.d(TAG, "updateWidget(). Sending broadcast to widget.");
Intent intent = new Intent(WidgetProvider.UPDATE);
intent.putExtra(WidgetProvider.UPDATE_ITEM, item.id);
sendBroadcast(intent);
}
我的小部件onReceived现在看起来像这样:
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(UPDATE)) {
Log.d(TAG, "onReceived detected new update");
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context); // 13
this.onUpdate(context, appWidgetManager, appWidgetManager
.getAppWidgetIds(new ComponentName(context,
WidgetProvider.class)),
intent.getExtras().getLong(WidgetProvider.UPDATE_ITEM));
} else {
super.onReceive(context, intent);
}
}
onUpdate的特殊修改版本是这样的:
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds, long itemId) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
if (items == null) {
items = ((ToDoExApp) ((ContextWrapper) context).getBaseContext()).itemsData;
}
Item item = items.getItem2(itemId);
if (item == null) {
Log.d(TAG, "Item with id = " + itemId + " not found.");
return;
}
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
Log.d(TAG, "updating widget " + appWidgetId);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.row);
views.setTextViewText(R.id.textViewShortName, item.title);
views.setTextViewText(R.id.textViewDesc, item.description);
views.setTextViewText(R.id.textViewDue,
new StringBuilder().append(item.dueDate).toString());
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
现在,每当我更改时,向数据库添加一个项目,就会向窗口小部件广播有关此项目的信息。然后它被接收和处理。但是,小部件上仅显示此项目。 Yamba应用程序(来自Learning Android)有一些非常相似的东西 - 每次找到更新时,它都会添加到窗口小部件中。我看到的唯一严重的区别是Yamba使用内容解析器,我使用数据库...
答案 0 :(得分:0)
我使用以下内容将项目添加到我的窗口小部件,如示例:
for(Server srv:mylist){
newView = new RemoteViews(context.getPackageName(), R.layout.widget_row);
newView.setTextViewText(R.id.servername,srv.getServerName());
newView.setTextViewText(R.id.serverstatus,srv.getServerStatus());
remoteViews.addView(R.id.widget,newView);
}
这基本上会向newView
remoteViews
编辑:
在2.2上运行小部件。可以根据您的情况拉伸窗口小部件 当然是发射器。
编辑:
尝试使用以下内容 在onUpdate()
中 ComponentName thisWidget = new ComponentName(context, MyWidget.class);
Item[] iii = items.getItemsArray();
RemoteViews rv = new RemoteViews(context.getPackageName(),
R.layout.widgetlayout);
for (Item item : iii) {
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.row);
views.setTextViewText(R.id.textViewShortName, item.title);
views.setTextViewText(R.id.textViewDesc, item.description);
views.setTextViewText(R.id.textViewDue, new StringBuilder()
.append(item.dueDate).toString());
rv.addView(R.id.llWidget, views);
}
appWidgetManager.updateAppWidget(thisWidget, rv);
我仍然不明白这是什么意思
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
工作示例: 您可能仍希望实施服务
public class StatusWidget extends AppWidgetProvider {
LayoutInflater inflater;
int[] appWidgetIds;
AppWidgetManager appWidgetManager;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
this.appWidgetIds=appWidgetIds;
this.appWidgetManager=appWidgetManager;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new MyTime(context, appWidgetManager), 1, 30000); //30 seconds timeout
}
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
final int appWidgetId = intent.getExtras().getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
this.onDeleted(context, new int[]{appWidgetId});
}
} else {
super.onReceive(context, intent);
}
}
private class MyTime extends TimerTask {
RemoteViews remoteViews;
AppWidgetManager appWidgetManager;
ComponentName thisWidget;
Context context;
public MyTime(Context context, AppWidgetManager appWidgetManager) {
this.context = context;
this.appWidgetManager = appWidgetManager;
remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_message);
thisWidget = new ComponentName(context, StatusWidget.class);
}
@Override
public void run() {
remoteViews.removeAllViews(R.id.widget);
Date date = new Date();
DateFormat format = SimpleDateFormat.getTimeInstance(
SimpleDateFormat.LONG, Locale.getDefault());
InputStream is = null;
ImageAdapter myServers =null;
List<Server> mylist =null;
try {
is = new ByteArrayInputStream(Utils.fetch("http://mystatusserver/status", null).toByteArray());
} catch (Exception cte) {
}
try {
String l = Utils.readInputStream(is);
List<Server> list= Utils.parseServers(l);
mylist= Utils.loadMyServerList(context, list);
} catch (Exception e) {
e.printStackTrace();
}
RemoteViews newView =null;
for(Server srv:mylist){
newView = new RemoteViews(context.getPackageName(), R.layout.widget_row);
newView.setTextViewText(R.id.servername,srv.getServerName());
newView.setTextViewText(R.id.serverstatus,srv.getServerStatus());
remoteViews.addView(R.id.widget,newView);
}
newView = new RemoteViews(context.getPackageName(), R.layout.datetime);
newView.setTextViewText(R.id.time,"Last Updated At: "+format.format(date));
remoteViews.addView(R.id.widget,newView);
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}
}
}
希望它有助于升技