widget的生命周期非常特别。创建方式如下:
(1)创建AndroidManifest.xml,注销主activity 的申明部分代码:
<!--
<activity android:name=".widgetProvider"
android:label="@string/app_name"> <intent-filter> <action
android:name="android.intent.action.MAIN" /> <category
android:name="android.intent.category.LAUNCHER" /> </intent-filter>
</activity>
-->
(2)增加在res/xml/下增加appwidget_provider.xml的申明
<?xml version="1.0" encoding="UTF-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="294dp" --这个代表占用四个格子宽度,(number of cells * 74) - 2
android:minHeight="72dp" --这个
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/main">
</appwidget-provider>
(3)派生类AppWidgetProvider,写自己的onUpdate和onReceive:
package com.terry;
import java.util.Timer;
import android.app.PendingIntent;
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.widget.RemoteViews;
import android.widget.Toast;
public class widgetProvider extends AppWidgetProvider {
public static final String CLICK_NAME_ACTION = "com.terry.action.widget.click";
private static RemoteViews rv;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
Timer timer = new Timer();
timer.scheduleAtFixedRate(new MyTime(context,appWidgetManager), 1, 300000);
}
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
if (rv == null) {
rv = new RemoteViews(context.getPackageName(), R.layout.main);
}
if (intent.getAction().equals(CLICK_NAME_ACTION)) {
Uri uri = Uri.parse("geo:38.899533,-77.036476");
Intent it = new Intent(Intent.ACTION_VIEW,uri);
context.startActivity(it);
}
AppWidgetManager appWidgetManger = AppWidgetManager
.getInstance(context);
int[] appIds = appWidgetManger.getAppWidgetIds(new ComponentName(
context, widgetProvider.class));
appWidgetManger.updateAppWidget(appIds, rv);
}
}
(4)如何动态界面元素。
widget设计和app类似,但控制动态元素则区别较大。
增加事件的方法,控件ID传入appWidgetId即可:
public static void updateAppWidget(Context context,
AppWidgetManager appWidgeManger, int controlID,String command) {
rv = new RemoteViews(context.getPackageName(), R.layout.main);
Intent intentClick = new Intent(command);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
intentClick, 0);
rv.setOnClickPendingIntent(controlID, pendingIntent);
ComponentName appWidgetId = new ComponentName(context,
widgetProvider.class);
appWidgeManger.updateAppWidget(appWidgetId, rv);
}
增加事件消息:
public static final String CLICK_NAME_ACTION = "com.terry.action.widget.click";
public static final String CLICK_FRESH_ACTION = "com.terry.action.widget.fresh";
在XML中需要增加响应:
<receiver android:name=".widgetProvider">
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/appwidget_provider"></meta-data>
<intent-filter>
<action android:name="com.terry.action.widget.click"></action>
<action android:name="com.terry.action.widget.fresh"></action>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</receiver>
最后在Onreciver中处理事件消息:
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
try {
if (rv == null) {
rv = new RemoteViews(context.getPackageName(), R.layout.main);
}
if (intent.getAction().equals( CLICK_NAME_ACTION)) { //to do
}}}
修改控件属性的方法择非常多,类似如下
rv.setTextViewText(R.id.TextView01,"hello");//rv.setImageViewResource(R.id.imageView2,R.drawable.zh3)
appWidgetManger.updateAppWidget(appIds, rv);