天天看點

Widget 視窗小部件

Widget 視窗小部件

Widget的簡介     App Widget是應用程式視窗小部件(Widget)是微型的應用程式視圖,它可以被嵌入到其它應用程式中(比如桌面)并接收周期性的更新。你可以通過一個App Widget Provider來釋出一個Widget。

Widget的使用步驟 1、建立一個類(其實是一個廣播接收者)繼承AppWidgetProvider 2、在AndroidManifest清單檔案中進行配置,在< meta-data/> 标簽中加載配置檔案 3、編寫Widget的配置檔案 xml/provider_info.xml,該檔案配置了widget可以占用的螢幕長寬、更新頻率,所顯示的布局檔案等 4、在layout中編寫布局檔案    

Widget的詳細講解 1、AppWidgetProvider類中的方法的講解  AppWidgetProvider 繼承自 BroadcastReceiver,它能接收 widget 相關的廣播,例如 widget 的更新、删除、開啟和禁用等。  AppWidgetProvider中的廣播處理函數如下: onUpdate()      當 widget 更新時被執行。 同樣,當使用者首次添加 widget 時,onUpdate() 也會被調用,這樣 widget 就能進行必要的設定工作(如果需要的話) 。但是,如果定義了 widget 的 configure屬性(即android:config,後面會介紹),那麼當使用者首次添加 widget 時,onUpdate()不會被調用;之後更新 widget 時,onUpdate才會被調用。 onAppWidgetOptionsChanged()      當 widget 被初次添加或者當 widget 的大小被改變時,執行onAppWidgetOptionsChanged()。你可以在該函數中,根據 widget 的大小來顯示/隐藏某些内容。可以通過 getAppWidgetOptions() 來傳回 Bundle 對象以讀取 widget 的大小資訊,Bundle中包括以下資訊:   OPTION_APPWIDGET_MIN_WIDTH -- 包含 widget 目前寬度的下限,以dp為機關。   OPTION_APPWIDGET_MIN_HEIGHT -- 包含 widget 目前高度的下限,以dp為機關。   OPTION_APPWIDGET_MAX_WIDTH -- 包含 widget 目前寬度的上限,以dp為機關。   OPTION_APPWIDGET_MAX_HEIGHT -- 包含 widget 目前高度的上限,以dp為機關。 onAppWidgetOptionsChanged() 是 Android 4.1 引入的。 onDeleted(Context, int[])      當 widget 被删除時被觸發。 onEnabled(Context)      當第1個 widget 的執行個體被建立時觸發。也就是說,如果使用者對同一個 widget 增加了兩次(兩個執行個體),那麼onEnabled()隻會在第一次增加widget時觸發。 onDisabled(Context)      當最後1個 widget 的執行個體被删除時觸發。 onReceive(Context, Intent)      接收到任意廣播時觸發,并且會在上述的方法之前被調用。 總結,AppWidgetProvider 繼承于 BroadcastReceiver。實際上,App Widge中的onUpdate()、onEnabled()、onDisabled()等方法都是在 onReceive()中調用的;是onReceive()對特定事情的響應函數。

2、AppWidgetProviderInfo的講解     AppWidgetProviderInfo描述一個App Widget中繼資料,比如App Widget的布局,更新頻率,以及AppWidgetProvider 類。這個應該在XML裡定義。下面以XML示例來對AppWidgetProviderInfo中常用的類型進行說明。

  1. <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
  2.   android:minWidth="40dp"
  3.   android:minHeight="40dp"
  4.   android:updatePeriodMillis="86400000"
  5.   android:previewImage="@drawable/preview"
  6.   android:initialLayout="@layout/example_appwidget"
  7.   android:configure="com.example.android.ExampleAppWidgetConfigure" 
  8.   android:resizeMode="horizontal|vertical"
  9.   android:widgetCategory="home_screen|keyguard"
  10.   android:initialKeyguardLayout="@layout/example_keyguard">
  11. </appwidget-provider>

示例說明: minWidth 和minHeight       它們指定了App Widget布局需要的最小區域。 預設的App Widgets所在視窗的桌面位置基于有确定高度和寬度的單元網格中。如果App Widget的最小長度或寬度和這些網格單元的尺寸不比對,那麼這個App Widget将上舍入(上舍入即取比該值大的最接近的整數——譯者注)到最接近的單元尺寸。   注意:app widget的最小尺寸,不建議比 “4x4” 個單元格要大。關于app widget的尺寸,後面在詳細說明。 minResizeWidth 和 minResizeHeight       它們屬性指定了 widget 的最小絕對尺寸。也就是說,如果 widget 小于該尺寸,便會因為變得模糊、看不清或不可用。 使用這兩個屬性,可以允許使用者重新調整 widget 的大小,使 widget 的大小可以小于 minWidth 和 minHeight。   注意:(01) 當 minResizeWidth 的值比 minWidth 大時,minResizeWidth 無效;當 resizeMode 的取值不包括 horizontal 時,minResizeWidth 無效。            (02) 當 minResizeHeight 的值比 minHeight 大時,minResizeHeight 無效;當 resizeMode 的取值不包括 vertical 時,minResizeHeight 無效。 updatePeriodMillis       它定義了 widget 的更新頻率。實際的更新時機不一定是精确的按照這個時間發生的。建議更新盡量不要太頻繁,最好是低于1小時一次。 或者可以在配置 Activity 裡面供使用者對更新頻率進行配置。 實際上,當updatePeriodMillis的值小于30分鐘時,系統會自動将更新頻率設為30分鐘!關于這部分,後面會詳細介紹。   注意: 當更新時機到達時,如果裝置正在休眠,那麼裝置将會被喚醒以執行更新。如果更新頻率不超過1小時一次,那麼對電池壽命應該不會造成多大的影響。 如果你需要比較頻繁的更新,或者你不希望在裝置休眠的時候執行更新,那麼可以使用基于 alarm 的更新來替代 widget 自身的重新整理機制。将 alarm 類型設定為 ELAPSED_REALTIME 或 RTC,将不會喚醒休眠的裝置,同時請将 updatePeriodMillis 設為 0。 initialLayout       指向 widget 的布局資源檔案 configure      可選屬性,定義了 widget 的配置 Activity。如果定義了該項,那麼當 widget 建立時,會自動啟動該 Activity。 previewImage      指定預覽圖,該預覽圖在使用者選擇 widget 時出現,如果沒有提供,則會顯示應用的圖示。該字段對應在 AndroidManifest.xml 中 receiver 的 android:previewImage 字段。由 Android 3.0 引入。 autoAdvanceViewId       指定一個子view ID,表明該子 view 會自動更新。在 Android 3.0 中引入。 resizeMode       指定了 widget 的調整尺寸的規則。可取的值有: "horizontal", "vertical", "none"。"horizontal"意味着widget可以水準拉伸,“vertical”意味着widget可以豎值拉伸,“none”意味着widget不能拉伸;預設值是"none"。Android 3.1 引入。 widgetCategory       指定了 widget 能顯示的地方:能否顯示在 home Screen 或 lock screen 或 兩者都可以。它的取值包括:"home_screen" 和 "keyguard"。Android 4.2 引入。 initialKeyguardLayout       指向 widget 位于 lockscreen 中的布局資源檔案。Android 4.2 引入。

3、Widget布局說明 3.1 添加 widget 到lock screen中

     預設情況下(即不設定android:widgetCategory屬性),Android是将widget添加到 home screen 中。      但在Android 4.2中,若使用者希望 widget 可以被添加到lock screen中,可以通過設定 widget 的 android:widgetCategory 屬性包含keyguard來完成。      當你把 widget 添加到lock screen中時,你可能對它進行定制化操作,以差別于添加到home screen中的情況。 你能夠通過 getAppWidgetOptions() 來進行判斷 widget 是被添加到lock screen中,還是home screen中。通過 getApplicationOptions() 擷取 Bundle對象,然後讀取 Bundle 的OPTION_APPWIDGET_HOST_CATEGORY值:若值為 WIDGET_CATEGORY_HOME_SCREEN, 則表示該 widget 被添加到home screen中; 若值為 WIDGET_CATEGORY_KEYGUARD,則表示該 widget 被添加到lock screen中。      另外,你應該為添加到lock screen中的 widget 單獨使用一個layout,可以通過 android:initialKeyguardLayout 來指定。而 widget 添加到home screen中的layout則可以通過 android:initialLayout 來指定。

3.3 App Widget支援的布局和控件 Widget并不支援所有的布局和控件,而僅僅隻是支援Android布局和控件的一個子集。 (01) App Widget支援的布局:   FrameLayout   LinearLayout   RelativeLayout   GridLayout (02) App Widget支援的控件:   AnalogClock   Button   Chronometer   ImageButton   ImageView   ProgressBar   TextView   ViewFlipper   ListView   GridView   StackView   AdapterViewFlipper

3.4 App Widget清單檔案的配置說明

  1. <!-- 桌面小視窗的Widget -->
  2. <receiver
  3. android:name="com.mobilesafe.receiver.MyWidget">
  4. <intent-filter >
  5. <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
  6. </intent-filter>
  7. <meta-data 
  8. android:name="android.appwidget.provider"
  9. android:resource="@xml/process_widget_provider" />
  10. </receiver>

說明: (01) MyWidget是繼承于的AppWidgetProvider類,用來響應widget的添加、删除、更新等操作。 (02) android.appwidget.action.APPWIDGET_UPDATE,必須要顯示聲明的action!因為所有的widget的廣播都是通過它來發送的;要接收widget的添加、删除等廣播,就必須包含它。 (03) action android:name="com.skywang.widget.UPDATE_ALL,這是我自己添加了,是為了接收服務所發送的更新圖檔的廣播。 (04) <meta-data> 指定了 AppWidgetProviderInfo 對應的資源檔案     android:name -- 指定metadata名,通過android.appwidget.provider來辨識data。     android:resource -- 指定 AppWidgetProviderInfo 對應的資源路徑。即,xml/process_widget_provider.xml。 (05) AppWidgetService 是用于更新widget中的圖檔的服務。 (06) android.appwidget.action.EXAMPLE_APP_WIDGET_SERVICE 用于啟動服務的action。