一、自定義widget必須繼承AppWidgetProviderandroid
源碼:http://www.jinhusns.com/Products/Download/?type=xcj數組
二、AndroidManifest.xml中必須註冊app
<receiver android:name=".widget.AppWidget" >ide
<meta-data佈局
android:name="android.appwidget.provider"ui
android:resource="@xml/guide_widget" />xml
<intent-filter>繼承
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />生命週期
</intent-filter>事件
</receiver>
(1)receiver的name必須爲自定義widget類名
(2)meta-data的name必須爲android.appwidget.provider
(3)meta-data 的resource爲該widget的描述文件,該文件必須放在res/xml路徑下
(4)須要添加action增長監聽receiver種類android.appwidget.action.APPWIDGET_UPDATE
三、res/xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/guide_widget"
android:minHeight="294.0dip"
android:minWidth="294.0dip"
android:updatePeriodMillis="1801000" />
(1)最外層標籤必須爲appwidget-provider
(2) android:initialLayout指定了widget使用的佈局文件
(3)android:minHeight指定了widget的高度,android:minWidth指定了widget的寬度。這兩個數值不能隨意 指定,最好根據須要放置的widget所佔據的屏幕行列數設定。例如,某widget爲3行2列,則minHeight應爲(3*74)- 2=220,minWidth應爲(2*74)-2=146
(4)android:updatePeriodMillis該值爲widget刷新時間,最好設置1小時以上,不然會嚴重浪費系統資源,耗電量會很大。每隔固定的該時間,系統就會調用該widget的onUpdate方法,若是該值爲0,則表示不更新widget
四、widget繼承自父類方法
(1)onEnabled(Context context)
該方法會在用戶添加widget後調用
(2)onUpdate(Context context, AppWidgetManager
appWidgetManager,int[] appWidgetIds)
該方法會在用戶添加widget後調用,用來刷新界面已經安裝的widget(在onEnabled以後調用)。
appWidgetManager參數用來執行刷新界面的操做
appWidgetIds是該應用程序全部widget的id(用戶可能添加多個,所以此處爲數組)
(3)onDeleted(Context context, int[] appWidgetIds)
該方法會在widget被刪除後調用(注意,是刪除後,也就是說,該方法不是執行刪除動做的)
(4)onReceive(Context context, Intent intent)
該方法是繼承自receiver的,儘可能不要使用,若是要使用,就須要你本身處理一些特殊代碼,不然widget就會出問題
五、界面widget的刷新及點擊事件
(1)在widget中,不能再使用findviewbyid方法獲取組件,須要使用其餘的方式。RemoteViews rv = new RemoteViews(context.getPackageName(),
R.layout.guide_widget);
RemoteViews 是一個虛構的組件,用它來承載layout。
(2) 點擊layout中的某個組件啓動activity或service
Intent intent = new Intent(context, WidgetDemoActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
rv.setOnClickPendingIntent(R.id.guide_0, pendingIntent);
(3) 界面刷新
appWidgetManager.updateAppWidget(appWidgetId, rv);
六、 widget支持在layout中使用的組件
FrameLayout、LinearLayout、RelativeLayout
AnalogClock、Button、Chronometer、ImageButton、ImageView、ProgressBar、TextView
七、 自定義widget類完整代碼
public class AppWidget extends AppWidgetProvider {
RemoteViews rv;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
System.out.println(context.getPackageName());
final int N = appWidgetIds.length;
// 由於有可能用戶添加了多個窗口小部件,因此這裏須要遍歷appWidgetIds
for (int i = 0; i < N; i++) {
System.out.println(appWidgetIds[i]);
int appWidgetId = appWidgetIds[i];
rv = new RemoteViews(context.getPackageName(),
R.layout.guide_widget);
Intent intent = new Intent(context, WidgetDemoActivity.class);
intent.setAction(context.getPackageName() + appWidgetId);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
intent, 0);
rv.setOnClickPendingIntent(R.id.guide_0, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, rv);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
}
八、 widget生命週期(android1.6)
(1) 當用戶拖拽widget到界面時,會按照順序分別調用以下幾個方法:onReceive-onEnabled-onReceive-onUpdate-onReceive-onReceive
(2) 當用戶拖拽widget刪除時,會按照順序分別調用以下幾個方法:
onReceive-onDeleted-onReceive-onDisabled