Android Widget(窗口小部件)

Android Widget簡介
應用程序窗口小部件(Widget)是微型的應用程序視圖,它能夠被嵌入到其它應用程序中(好比桌面)並接收週期性的更新。你能夠經過一個App Widget Provider來發佈一個Widget。能夠容納其它App Widget的應用程序組件被稱爲App Widget宿主程序.
    爲了建立一個App Widget,你須要使用下面這些:
  1.AppWidgetProviderInfo 對象(定義在XML文件裏面)
    描述一個App Widget元數據,好比App Widget的佈局,更新頻率,以及AppWidgetProvider 類。這個應該在XML裏定義。
  2.AppWidgetProvider 類的實現(主要是接收廣播並進行相應操做)
    定義基本方法以容許你經過編程來和App Widget通訊,這基於廣播事件。經過它,當App Widget被更新、可用、禁用和刪除的時候,都將接收到廣播通知。
  3.視圖佈局
    在XML中定義App Widget初始佈局。
    另外,你能夠實現App Widget配置Activity 。這是一個可選的Activity,當用戶添加App Widget時加載它並容許用戶修改App Widget的設置。(當用戶添加到桌面時會自動調用該Activity)
 
Android Widget具體使用
  1.首先,在應用程序AndroidManifest.xml文件中聲明AppWidgetProvider 類
 <receiver android:name="ExampleAppWidgetProvider" >     
     <intent-filter>          
      <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />     
    </intent-filter>      
    <meta-data android:name="android.appwidget.provider"                 
      android:resource="@xml/example_appwidget_info" /> 
    </receiver>  

說明:html

  <receiver>元素須要android:name屬性,指定了App Widget使用的AppWidgetProvider 。
  <intent-filter>元素必須包括一個含有android:name屬性的<action>元素。該元素指定AppWidgetProvider接受ACTION_APPWIDGET_UPDATE 廣播。這是惟    一你必須顯式聲明的廣播。當須要的時候,必要時AppWidgetManager會自動發送全部其它App Widget廣播給AppWidgetProvider。
  <meta-data> 元素指定了AppWidgetProviderInfo 資源並須要如下屬性:
    • android:name–指定元數據名稱,使用android.appwidget.provider 來 肯定AppWidgetProviderInfo描述的數據。
    • android:resource–指定AppWidgetProviderInfo 資源路徑
 2.添加AppWidgetProviderInfo元數據
    AppWidgetProviderInfo定義一個App Widget的基本特性,好比最小布局尺寸,初始佈局資源,刷新頻率,以及建立時加載的一個配置Activity(可選的)。使用單獨的一個<appwidget-provider>元素在XML資源裏定義AppWidgetProviderInfo 對象並保存到項目的res/xml/目錄下
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"  
    android:minWidth="294dp"  
    android:minHeight="72dp"  
    android:updatePeriodMillis="86400000"  
    android:initialLayout="@layout/example_appwidget"  
    android:configure="com.example.android.ExampleAppWidgetConfigure" >  
</appwidget-provider>  

  下面是<appwidget-provider>屬性的總結: java

  a)minWidth 和minHeight 屬性的值指定了App Widget佈局須要的最小區域。android

  缺省的App Widgets所在窗口的桌面位置基於有肯定高度和寬度的單元網格中。若是App Widget的最小長度或寬度和這些網格單元的尺寸不匹配,那麼這個App Widget將上舍入(上舍入即取比該值大的最接近的整數——譯者注)到最接近的單元尺寸。數據庫

  通常說來桌面佈局方向能夠變化(由此單元的尺寸也會變化),你應該假設最壞狀況即單元尺寸高和寬是74像素。不過,你必須從最終的尺寸中減去2以把像素計算過程當中產生的任何的整數舍入偏差考慮在內。要找到像素密度無關的最小寬度和高度,使用這個公式:(number of cells * 74) - 2.依據這個公式,你應該使用72dp做爲高度,294dp做爲寬度。編程

  b)updatePerdiodMillis 屬性定義了App Widget框架調用onUpdate()方法來從AppWidgetProvider請求一次更新的頻度。實際更新時間並不那麼精確,並且咱們建議更新頻率越低越好——最好每小時不超過一次以節省電源。你也許還會容許用戶在配置中調整這個頻率——一些人可能想每15分鐘一次股票報價,或者一天只要四次。app

  注意:當到個更新的時間時,若是設備處於休眠狀態,則設備將會被喚醒來執行更新操做。若是更新頻率每小時不超過一次,這可能對電池的壽命不會產生值得注意的問題。可是,若是更新的很頻繁,或者當設備處於休眠狀態時不更新,那麼你最好使用一個alarm來代替執行更新操做,這樣不會喚醒設備。這種方式能夠經過使用AlarmManager類實現。設置alarm的類型爲 ELAPSED_REALTIME或者RTC,這兩種類型只有在設備處於喚醒狀態時纔會傳遞alarm,同時設置updatePeriodMillis 爲0.框架

  c)initialLayout屬性指向定義App Widget佈局的資源。ide

  d)configure屬性定義了當用戶添加App Widget時啓動的Activity,配置App Widget特性。這是可選的函數

3.建立App Widget佈局oop

    你必須在XML中爲你的App Widget定義一個初始佈局並保存到項目的res/layout/ 目錄下。你可使用以下所列的View對象來設計你的App Widget,可是,你必須注意App Widget佈局是基於RemoteViews, 而RemoteViews並不支持全部類型的佈局或視圖小部件。

  一個RemoteViews對象(對應的,一個App Widget)能夠支持下面這個佈局類(可是不支持這些類的派生):

    • FrameLayout 
    • LinearLayout 
    • RelativeLayout 

  以及下面的控件類:

    • AnalogClock 
    • Button 
    • Chronometer 
    • ImageButton 
    • ImageView 
    • ProgressBar 
    • TextView 
4.使用AppWidgetProvider類
    AppWidgetProvider類擴展自BroadcastReceiver ,做爲處理App Widget廣播一個簡便類,AppWidgetProvider只接收和這個App Widget相關的事件廣播,好比這個App Widget被更新、刪除、啓用以及禁用。當這些廣播事件發生時,AppWidgetProvider 將接收到下面的方法調用:
  onUpdate(Context, AppWidgetManager, int[]) //最經常使用的由於它是在每一個App Widget添加進宿主時被調用的(除非你使用一個配置活動)
    這個方法調用來間隔性的更新App Widget,間隔時間用AppWidgetProviderInfo 裏的updatePeriodMillis屬性定義。這個方法也會在用戶添加App Widget時被調用,所以它應該執行必要的設置,好比爲控件定義事件處理器並啓動一個臨時的服務Service,若是須要的話。可是,若是你已經聲明瞭一個配置Activity,這個方法在用戶添加App Widget時將不會被調用,而只在後續更新時被調用。配置Activity有責任在配置完成時負責執行第一次更新。
  onDeleted(Context, int[]) 
    當App Widget從宿主App Widget  中刪除時被調用。
  onEnabled(Context) 
    當一個App Widget實例第一次建立時被調用。好比,若是用戶添加兩個你的App Widget實例,只在第一次被調用。若是你須要打開一個新的數據庫或者執行其餘對於全部的App Widget實例只須要發生一次的設置,那麼這裏是完成這個工做的好地方。
  onDisabled(Context) 
    當你的App Widget的最後一個實例被從宿主中刪除時被調用。你應該在onEnabled(Context)中作一些清理工做,好比刪除一個臨時的數據庫。
  onReceive(Context, Intent) 
    這個接收到每一個廣播時都會被調用,並且在上面的回調函數以前。你一般不須要實現這個方法,由於缺省的AppWidgetProvider 實現過濾全部App Widget 廣播並恰當的調用上述方法。
public class ExampleAppWidgetProvider extends AppWidgetProvider {  
  
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {  
        final int N = appWidgetIds.length;  
  
        // Perform this loop procedure for each App Widget that belongs to this provider  
        for (int i=0; i<N; i++) {  
            int appWidgetId = appWidgetIds[i];  
  
            // Create an Intent to launch ExampleActivity  
            Intent intent = new Intent(context, ExampleActivity.class);  
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);  
  
            // Get the layout for the App Widget and attach an on-click listener to the button  
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);  
            views.setOnClickPendingIntent(R.id.button, pendingIntent);  
  
            // Tell the AppWidgetManager to perform an update on the current App Widget  
            appWidgetManager.updateAppWidget(appWidgetId, views);  
        }  
    }  
}    
    注意: 由於這個AppWidgetProvider 是一個廣播接收器BroadcastReceiver,不能保證你的進程在回調函數返回後仍然繼續運行。若是你的App Widget設置過程能持續幾秒鐘(好比當執行網頁請求時)並且你要求你的進程繼續,考慮在onUpdated()方法裏啓動一個服務Service。從這個服務裏,你能夠執行本身的App Widget更新,而沒必要擔憂AppWidget Provider 因爲一個應用程序無響應錯誤Application Not Responding (ANR)而關閉。
   AppWidgetProvider 只是一個簡便類。若是你想直接接收App Widget廣播,你能夠實現本身的BroadcastReceiver 或者重寫 onReceive(Context, Intent) 回調函數。你須要注意以下4個Intents
  • ACTION_APPWIDGET_UPDATE 
  • ACTION_APPWIDGET_DELETED 
  •  ACTION_APPWIDGET_ENABLED 
  • ACTION_APPWIDGET_DISABLED 
5.建立一個App Widget 配置Activity()
   若是你想讓用戶在添加一個新的App Widget時調整設置,你能夠建立一個App Widget配置Activity 。這個Activity 將被App Widget宿主自動啓動並容許用戶在建立時配置可用的設置,好比App Widget顏色,尺寸,更新週期或者其它功能設置。 
   這個配置Activity應該在Android清單文件中聲明爲一個通用Activity。不過,它將被經過ACTION_APPWIDGET_CONFIGUREaction而被App Widget宿主啓動,所以這個Activity須要接受這個Intent 。好比:
<activity android:name=".ExampleAppWidgetConfigure">  
  <intent-filter>  
    <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> 
  </intent-filter>  
</activity>  

  固然,Activity必須在AppWidgetProviderInfo XML 文件中聲明,經過android:configure屬性。好比,配置Activity能夠聲明以下:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"  
    ...  
    android:configure="com.example.android.ExampleAppWidgetConfigure"   
    ... >  
</appwidget-provider>  
  注意這個Activity是用全包名聲明的,由於它將從你的程序包外被引用。
   這就是全部關於配置活動你一開始須要瞭解的。如今你須要一個真實的Activity。這兒就有,不過,當你實現這個Activity時記住兩件重要的事情:
    • App Widget 宿主調用配置Activity並且配置Activity應該老是返回一個結果.這個結果應該包含這個經過啓動該活動的意圖傳遞App Widget ID(以EXTRA_APPWIDGET_ID保存在Intent的附加段Intent extras中) 
    • 當這個 App Widget 被建立時將不會調用onUpdate() 方法(當一個配置活動啓動時,系統將不會發送ACTION_APPWIDGET_UPDATE廣播).配置活動應該在 App Widget 第一次被建立時負責從AppWidgetManager請求一個更新.不過, onUpdate() 將在後續更新中被調用-只忽略第一次.

 

從配置Activity中更新一個App Widget


 

  當一個App Widget使用一個配置Activity,那麼當配置結束時,就應該由這個Activity來更新這個App Widget.你能夠直接經過AppWidgetManager請求一次更新操做.下面是恰當的更新App Widget 以及關閉配置Activity這個過程的一個概要描述:

  1.首先,從啓動這個Activity的Intent中獲取App Widget ID:  

Intent intent = getIntent();  
Bundle extras = intent.getExtras();  
if (extras != null) {  
    mAppWidgetId = extras.getInt(  
            AppWidgetManager.EXTRA_APPWIDGET_ID,   
            AppWidgetManager.INVALID_APPWIDGET_ID);  
} 

  2.實施你的App Widget 配置。

   3.當配置完成後,經過調用getInstance(Context)獲取一個AppWidgetManager實例:   

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);  
  4.以一個RemoteViews佈局調用updateAppWidget(int, RemoteViews)更新App Widget: 
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget);  
appWidgetManager.updateAppWidget(mAppWidgetId, views);  
  5.最後,建立返回Intent ,設置到Activity結果,並結束這個Activity: 
Intent resultValue = new Intent();  
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);  
setResult(RESULT_OK, resultValue);  
finish();  

  提示: 當你的配置Activity  第一次打開時,設置Activity 結果爲RESULT_CANCELED。這樣,若是用戶在結束以前從Activity 外返回,這個App Widget宿主會接收到配置取消通知而不會添加這個App Widget。

實例代碼位於APIDemos中。

相關文章
相關標籤/搜索