android API 11 RemoteViews 提供出一些新的方法,让我们可以在桌面widget上添加一些复杂界面元素。
比较有代表性的是 ListView。就此写贴做个记录与分享。
源码
http://download.csdn.net/detail/yarkey09/6513753
效果图
AndroidManifest.xml
请注意加入权限:android:permission="android.permission.BIND_REMOTEVIEWS
否则我们定义的Service不会onBind,待会Factory的代码就不会被调用。
AppWidgetProvider.java
package com.yarkey.remoteviewstest;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.widget.RemoteViews;
public class MyWidget extends AppWidgetProvider {
private static final String TAG = "MyWidget";
/** package */
static ComponentName getComponentName(Context context) {
return new ComponentName(context, MyWidget.class);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.d(TAG, "onUpdate");
performUpdate(context, appWidgetManager, appWidgetIds, null);
}
private void performUpdate(Context context, AppWidgetManager awm, int[] appWidgetIds, long[] changedEvents) {
for (int appWidgetId : appWidgetIds) {
Log.d(TAG, "appWidgetId = " + appWidgetId);
Intent intent = new Intent(context, MyWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.layout_widget);
views.setTextViewText(R.id.button1, "已更新");
views.setRemoteAdapter(R.id.listView1, intent);
awm.updateAppWidget(appWidgetId, views);
awm.notifyAppWidgetViewDataChanged(appWidgetId, R.id.listView1);
}
}
}
关键就是:views.setRemoteAdapter( int viewId, Intent intent )
这个方法在API 14才有。API 11相同方法 setRemoteAdapter( int appWidgetId, int viewId, Intent intent )
RemoteViewsService.java
package com.yarkey.remoteviewstest;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
public class MyWidgetService extends RemoteViewsService {
private static final boolean DB = true;
private static final String TAG = "MyWidgetService";
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
log("onGetViewFactory, intent=" + intent);
return new MyWidgetFactory(getApplicationContext(), intent);
}
public static class MyWidgetFactory implements RemoteViewsService.RemoteViewsFactory {
private Context mContext;
private String[] mFoods = new String[] { "Apple", "Banana", "Pear", "Handset", "People", "Bar", "Wind", "Song",
"Source code", "Screen", "Package", "Cup", "Computer" };
// 构造
public MyWidgetFactory(Context context, Intent intent) {
log("MyWidgetFactory");
mContext = context;
}
@Override
public int getCount() {
log("getCount");
return mFoods.length;
}
@Override
public long getItemId(int position) {
log("getItemId");
return position;
}
// 在调用getViewAt的过程中,显示一个LoadingView。
// 如果return null,那么将会有一个默认的loadingView
@Override
public RemoteViews getLoadingView() {
log("getLoadingView");
return null;
}
@Override
public RemoteViews getViewAt(int position) {
log("getViewAt, position=" + position);
if (position < 0 || position >= getCount()) {
return null;
}
RemoteViews views = new RemoteViews(mContext.getPackageName(), R.layout.layout_item);
views.setTextViewText(R.id.textView1, mFoods[position]);
return views;
}
@Override
public int getViewTypeCount() {
log("getViewTypeCount");
return 1;
}
@Override
public boolean hasStableIds() {
log("hasStableIds");
return true;
}
@Override
public void onCreate() {
log("onCreate");
}
@Override
public void onDataSetChanged() {
log("onDataSetChanged");
}
@Override
public void onDestroy() {
log("onDestroy");
}
}
private static void log(String log) {
if (DB)
Log.d(TAG, log);
}
}
有点类似BaseAdapter, getCount(), getViewAt()
-- end --