【安卓筆記】Widget,安卓widget
什麼是Widget?App Widget是android提供的案頭小工具,它能夠嵌入到案頭,並且可以定期更新自己的資料。
如所示:
如何建立Widget?
建立一個Widget需要以下幾個組件:
1AppWidgetProviderInfo:這個類提供了Widget的中繼資料,比如Widget的布局,更新頻率,大小等等。它通常都使用xml定義,位置為res/xml。
2.AppWidgetProvider:這個類是一個廣播接收者,用來接收一些廣播資訊,比如widget是否可用、widget更新、widget被刪除等。通常,我們需要繼承這個類並複寫onXXX等生命週期方法。
3.Widget布局:建立Widget需要指定其布局,這個在res/layout下定義即可。
4.AppWidgetManager:這個類可以更新Widget的狀態,並可以擷取已經註冊的AppWidgetProvider的資訊。
建立Widget的步驟:
1.定義一個類繼承AppWidgetProvider:
package com.example.widget;import android.appwidget.AppWidgetManager;import android.appwidget.AppWidgetProvider;import android.content.Context;public class MyWidgetProvider extends AppWidgetProvider{@Overridepublic void onEnabled(Context context){super.onEnabled(context);}@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds){super.onUpdate(context, appWidgetManager, appWidgetIds);}@Overridepublic void onDisabled(Context context){super.onDisabled(context);}}
2.在res/layout下定義widget的布局:比如叫widget_layout.xml
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="2dp" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"android:orientation="horizontal" > <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="開啟軟體" android:textColor="@android:color/black" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="這是一個widget" /> </LinearLayout></FrameLayout>
3.在res/xml目錄下建立一個xml資源,定義widget的基本資料:比如叫:app_widget_info.xml
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/widget_layout" android:minHeight="50dp" android:minWidth="290dp" android:updatePeriodMillis="86400000" ></appwidget-provider>
還有一些其他標籤,用法參見文檔。
4.在資訊清單檔中配置AppWidgetProvider:
<receiver android:name="com.example.widget.MyWidgetProvider" > <intent-filter><!--action name是固定的--> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/app_widget_info" /></receiver>
至此,Widget建立完成,效果如下:
這時候的button是沒有點擊效果的,那麼如何為其增加按鈕點擊的響應事件呢?那就要使用到AppWidgetManager了。在這之前我們先介紹下
Widget的生命週期,可以在上面MyWidgetProvider中打log,通過分析log我們可以得出如下結論:
1.第一個widget被拖到案頭上:onEnabled()--->onUpdate()
2.以後每個widget被拖到案頭上:onUpdate()
3.刪除一個Widget:onDeleted()
4.最後一個widget被刪除:onDeleted()-->onEnabled()另外,如果你複寫了onReceive方法,那麼onReceive方法是最先執行的(確保要調用super.onReceive)。其實我們分析下AppWidgetProvider源碼就很容易看出來,AppWidgetProvider在onReceive方法中通過判斷action類型,來執行不同的業務方法,而具體的業務方法是由子類來複寫的。
5.添加響應事件既然每個widget被拖到案頭都會調用onUpdate,那麼我們就在這個方法中為按鈕添加監聽:
@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds){Log.d(TAG,"onUpdate...");RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.widget_layout);PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent(context,MainActivity.class),0);views.setOnClickPendingIntent(R.id.btn, pendingIntent);appWidgetManager.updateAppWidget(appWidgetIds, views);}這裡需要用到AppWidgetManager的updateAppWidget方法,這個方法需要傳入widget的id和RemoteViews。這個RemoteViews很關鍵,我們要為按鈕添加響應事件,就得調用這個類的setOnClickPendingIntent方法,當然了,它也提供了很多其他方法,諸如setTextViewText、setProgressBar等,這些方法有個共同點,那就是必須傳入view的id。更多用法請查看文檔。通過上面的方法,當我們點擊按鈕時,就可以開啟主介面了!
widget通常需要配合service使用。因為,widget需要定時更新資訊,所以一個後台服務必不可少。這時候我們可以再onEnabled中啟動服務,然後在服務中增加一個定時器(Timer或者AlarmManager),定期更新widget,這時候可以通過
AppWidgetManager.getInstance(context);
擷取AppWidgetManager執行個體。
以上是widget的基本用法,更多用法參見文檔。