應用小部件是可以包含在其他應用程序(如主屏幕)中并定期更新的迷你應用程序視圖。
這些視圖在用戶界面中被叫做小部件,并可以用應用小部件提供者發(fā)布。可以容納其他應用部件的應用組件叫做應用部件的宿主(1)。下面的截圖顯示了音樂應用部件。本文檔描述了如何使用應用部件提供者發(fā)布應用小部件。關于創(chuàng)建自己的應用部件宿主來容納應用部件,請參考應用部件宿主。
小部件設計
如何設計自己的小部件的信息,請閱讀小部件設計向?qū)А?/p>
基礎知識
要創(chuàng)建應用小部件,你需要如下:
AppWidgetProviderInfo對象。 描述應用部件的元數(shù)據(jù),如應用部件的布局,更新頻率,和AppWidgetProvider類。這些應該XML中定義。
AppWidgetProviderclass 實現(xiàn)。 定義可以根據(jù)廣播事件讓你以編程方式與應用部件交互的基礎方法。通過它,你將將收到應用部件更新,啟用,禁止,和刪除的廣播。
視圖布局 定義應用部件的初始布局,這些布局定義在XML中。
此外,你可以實現(xiàn)一個應用部件配置活動。這是一個可選的活動。它在用戶添加你的應用部件時啟動,并且讓他或她可以在創(chuàng)建時修改應用部件設置。
下面的小節(jié)描述了如何建立這些組件中的每一個。
在清單中聲明應用部件
首先,在應用的AndroidMani的中聲明AppWidgetProvider類。例如:
元素需要android:name屬性,它指定了應用組件使用的AppWidgetProvider。
元素必須包含在元素中并帶有android:name屬性。這個屬性指明AppWidgetProvider接受ACTION_APPWIDGET_UPDATE廣播。這是你唯一必須明確聲明的廣播。AppWidgetManager會在適當?shù)臅r候向所有的AppWidgetProvider發(fā)送應用部件廣播。
元素指定AppWidgetProviderInfo資源并需要如下屬性:
android:name - 指定元數(shù)據(jù)名稱。使用android.a標識這個數(shù)據(jù)為AppWidgetProviderInfo描述符。
android:resource - 指定AppWidgetProviderInfo資源位置。
添加AppWidgetProviderInfo元數(shù)據(jù)
AppWidgetProviderInfo定義了應用部件的必要特性,例如最小布局尺寸,它的初始布局資源,多長時間更新應用部件,和(可選的)創(chuàng)建時啟動的配置活動。使用一個單獨的元素在XML資源中定義AppWidgetProviderInfo對象并獎它保存在工程的res/xml/文件夾。
例如:
這里是屬性的一個總結(jié):
minWidth和minHeight的屬性值指定了默認情況下應用部件占用的最小空間。默認主屏幕根據(jù)擁有已定義高寬的單元格來在它的窗體中定位應用部件。如果應用部件的最小寬度或高度值未匹配這些單元格的尺寸,那么應用部件的尺寸算到最近的單元格大小。
查看應用部件設計引導了解更多關于調(diào)整應用部件大小的信息。
注意:為了讓你的應用部件可在設備間移植,它的最小尺寸應該永遠大于4x4個單元格。
minResizeWidth和minResizeHeight屬性指定了應用部件的絕對最小尺寸。這些值應該指定低于該值應用部件會難以識別或者不可用的大小。使用這些屬性允許用戶將大小調(diào)整為可能小于minWidth和minHeight屬性的大小。安卓系統(tǒng) 3.1版本 引入。
查閱應用部件設計向?qū)Я私飧嚓P于調(diào)正應用部件大小的信息。
updatePeriodMillis屬性定義了應用部件框架應該多長時間通過調(diào)用onUpdate回調(diào)方法來從AppWidgetProvider請求更新。實際的更新不保證正好在這個時間發(fā)生,并且我們建議盡可能少地更新——也許不超過1小時一次以節(jié)省電量。你可能想讓用戶在配置中調(diào)整頻率——有些人可能想要一個自動計數(shù)器每15分鐘更新一次,或一天僅更新4次。
注意:如果設備在是時候更新(由updatePeriodMillis定義)的時候休眠,那時設備將喚醒以執(zhí)行更新。如果不超過一小時一次更新,這才不會引起影響電池壽命的顯著問題。但是,如果你需要更頻繁地更新,且/或不需要在設備休眠的時候更新,那么你換而可以基于不會喚醒設備的警報來執(zhí)行更新。使用AlarmManager建立一個帶有你的應用部件提供者接收的意圖的警報做到這點。將警報類型設為ELAPSED_REALTIME或RTC,它將僅會在設備喚醒時發(fā)送警報。然后設置updatePeriodMillis為0(“0”)。
initialLayout屬性指向定義應用部件布局的布局資源。
configure屬性定義了當用戶添加該應用部件時啟動的活動,為了讓他或她來配置應用部件的屬性。這是可選的(閱讀下面的創(chuàng)建應用部件配置活動)。
previewImage屬性指定了應用部件在配置后將是什么樣子的預覽,它是用戶選擇應用部件時所看到的東西。如果沒有提供,用會換而看到你的應用啟動圖標。 這個字段對應于AndroidMani文件中元素的android:previewImage屬性。更多關于usingpreviewImage的討論,參閱選擇預覽圖像。安卓3.0版本引入。
autoAdvanceViewId屬性指定應該由部件的宿主自動升級的應用部件子視圖的視圖ID。安卓系統(tǒng)3.0版本引入。
resizeMode屬性指定調(diào)整部件大小的規(guī)則。 你可以使用這個屬性來讓主屏幕小部件可以在水平,和素質(zhì),或同時兩個方向上調(diào)整方向。用戶按住部件來顯示它的大小調(diào)節(jié)手柄,然后拖拽水平和/或垂直手柄來改變其占用布局單元格的大小。該屬性的值包括“horizontal(水平)”,“vertical(垂直)”,和"none(無)"。想要聲明部件為水平和垂直方向可調(diào)節(jié)大小,將該值設為“horizontal|vertical”。安卓系統(tǒng)3.1版本。
minResizeHeight屬性指定部件可以調(diào)整的最小高度(單位dps)。這個字段在高于最小高度或未啟用高度大小調(diào)整(參考resizeMode) 時無效。安卓系統(tǒng)4.0版本引入。
minResizeWidth屬性指定部件可以調(diào)整的最小寬度(單位dps)。這個字段在大于最小寬度或未啟用寬度大小調(diào)整(參考resizeMode)時無效。安卓系統(tǒng)4.0版本引入。
widgetCategory屬性聲明你的應用部件是否可以顯示在主屏幕,鎖屏(鍵盤鎖),或兩者上面。該屬性的值包括"home_screen"和"keyguard"。顯示在兩者上面的部件需要遵循兩者部件類的設計向?qū)?。要了解更多信息,參考在鎖屏上啟用應用部件。默認值是"home_screen"。安卓系統(tǒng)4.2版本引入。
initialKeyguardLayout屬性指向鎖屏應用部件布局的布局資源。 這與android:initialLayout的工作方式相同,這種方式提供了應用部件初始后可以立即顯示的布局并且可以更新該布局。安卓系統(tǒng)4.2版本引入。
參考AppWidgetProviderInfo類中元素接收的屬性了解更多信息。
創(chuàng)建應用部件布局
你必須在XML中為你的應用定義初始布局并將它保存在項目的res/layout/目錄。你可以用下面列出的視圖對象設計你的應用部件,但是,在你開始設計你的應用部件之前,請閱讀理解應用部件向?qū)А?/p>
如果你熟悉布局,那么創(chuàng)建應用部件布局是簡單的。但是,你必須知道應用部件布局是基于RemoteViews的,它不支持各種布局和視圖部件。
RemoteView 對象 (并且,所以,也是一個應用部件) 可以支持如下布局類:
和如下部件類:
不支持這些類的后裔。
RemoteView也支持ViewStub,它是一個不可見的,大小為0的視圖,你可以在運行時延遲為它填充布局資源。
給應用部件添加邊距
部件通常不應該延伸到屏幕邊緣并且不應該在視覺上與其他部件齊平,因此你應該在你的部件框架(2)四周所有邊上增加邊距。
由于在安卓系統(tǒng)4.0版本中,應用部件會被自動地在部件框架和應用部件邊框之間給予填充,以提供與其他部件和用戶主屏幕上的圖標的更好的對齊。要利用這個強烈推薦行為的優(yōu)勢,將應用的targetSdkVersion設為14或更高。
寫一個單獨的擁有應用于早期平臺版本的自定義邊距,且在安卓4.0或更高版本沒有多余邊距的布局是容易的:
設置應用的targetSdkVersion為14或更高。
創(chuàng)建一個如下的布局,它為自己的邊距引用了尺寸資源:
創(chuàng)建兩個尺寸資源,一個是在res/values/中用于提供安卓4.0之前版本的自定義邊距資源,一個是在/res/values-v14/中用于提供給安卓4.0版本部件的無多余邊距資源:
res/value:
res/values-v14:
另一種選擇是簡單地在默認情況下建立額外的邊距到9宮格拉伸圖片(譯者注:橫豎分成9份,中間5格是可重復像素的圖片,一般用于常用的窗體背景)背景資源中,并為API級別14(譯者注:就是安卓4.0版本,這是它的相應的API版本),或之后的版本提供沒有邊距的9宮格圖片。
使用AppWidgetProvider類
你必須在AndroidManifest(參考上面的在清單文件中聲明應用部件)中使用元素將AppWidgetProvider類實現(xiàn)聲明為廣播接收者。
AppWidgetProvider擴展了BroadcastReceiver類作為一個方便處理應用部件廣播的類。AppWidgetProvider僅接收與應用部件相關的事件廣播,例如當應用部件被更新,刪除,啟用,禁用的時候。當這些廣播事件發(fā)生時,AppWidgetProvider接受如下方法調(diào)用:
onUpdate這個方法被調(diào)用以在每經(jīng)過一段間隔更新應用部件,這段間隔由AppWidgetProviderInfo(參考上面的添加AppWidgetProviderInfo元數(shù)據(jù)小節(jié))中的updatePeriodMillis屬性定義。這個方法也在用戶添加該應用部件時調(diào)用,因此它應該執(zhí)行一些必要的設置,例如定義視圖的事件處理和必要時創(chuàng)建一個臨時的服務。但是,如果你聲明了一個配置活動,那么在用戶添加應用部件時不會調(diào)用該方法,但是它會被后續(xù)的更新調(diào)用。用戶配置活動有責任在配置完成后執(zhí)行首次更新。(參考上面的創(chuàng)建應用部件配置活動)
onAppWidgetOptionsChanged這個方法在部件被首次放置和在任何部件被重新調(diào)正大小的時候調(diào)用。你可以用這個方法來顯示或隱藏部件尺寸范圍內(nèi)的內(nèi)容。你可以同過調(diào)用getAppWidgetOptions來獲得尺寸大小,這個方法返回一個包含如下的包(譯者注:內(nèi)存數(shù)據(jù)包bundle):
這個回調(diào)函數(shù)在API級別16引入(安卓4.1版本)。如果你實現(xiàn)了這個回調(diào)函數(shù),確保你的應用不會依賴它,因為它不會在舊的設備上被調(diào)用。
onDeleted(Context, int[]) 這個方法在每次應用部件被從應用部件的宿主刪除時調(diào)用。
onEnabled(Context)這個方法在應用部件的實例首次被創(chuàng)建時調(diào)用。例如,如果用戶添加了兩個你的應用部件的實例,該方法僅在第一次添加時調(diào)用。如果你需要打開一個新的數(shù)據(jù)庫或執(zhí)行其他需要為所有應用部件實例執(zhí)行一次的設置,那么這是做這件事的好地方。
onDisabled(Context)這個方法在最后一個應用部件的實例被從應用部件宿主刪除的時候調(diào)用。這是應該清理任何在onEnabled(Context)已完成工作的地方,例如刪除臨時數(shù)據(jù)庫。
onReceive(Context, Intent)這個方法在每次廣播的時候被調(diào)用并且在上述個回調(diào)方法之前。你通常不需要實現(xiàn)這個方法,因為默認AppWidgetProvider實現(xiàn)過濾了所有應用部件廣播并調(diào)用上述相應的方法。
最終要的AppWidgetProvider回調(diào)方法就是onUpdate,因為它在每個應用部件被添加到應用部件宿主時調(diào)用(除非你使用配置活動)。如果你的應用部件接受了任何用戶的交互事件,那么你需要在回調(diào)方法中注冊事件處理方法。如果你的應用沒創(chuàng)建臨時的文件或數(shù)據(jù)庫,或執(zhí)行其他需要清理的工作,那么onUpdate可能是你唯一要定義的回調(diào)方法。例如,你想要一個帶有點擊時啟動應用的應用部件,那么你可能要使用如下AppWidgetProvider的實現(xiàn):
AppWidgetProvider僅定義了onUpdate方法用于定義一個啟動活動的掛起意圖然后使用setOnClickPendingIntent(int, PendingIntent)將它附加到應用部件的按鈕上。注意,它包含了一個循環(huán),遍歷appWidgetIds中的每一個元素,這是標識這個提供者創(chuàng)建的每個應用部件的ID數(shù)組。 以這種方式,如果用戶創(chuàng)建應用部件的多個實例,那么他們都會同時更新。但是, 只有一個updatePeriodMillis的周期(譯者注:這里就是更新的時間間隔,原詞:schedule,大意是計劃的時間表,我的理解是要表達為計劃的周期,這里直接省略為周期)將被應用于所有應用部件的實例。例如,如果更新周期定義為兩小時,然后另一個部件的實例在第一個之后添加了一小時,那么他們都會按照第一個定義的間隔更新并且第二個更新間隔會被忽略(他們都會每兩小時更新,而不是每一小時)。
注意:因為AppWidgetProvider是BroadcastReceiver的擴展,你的進程在這個回掉方法返回之后不能保證會繼續(xù)運行(參考BroadcastReceiver了解更多關于廣播生命周期的信息)。如果你的應用部件創(chuàng)建進程可能會占用幾秒鐘(或許在執(zhí)行網(wǎng)頁請求)并且你要想進程繼續(xù),考慮下在onUpdate方法中啟動一個服務。你可以在服務中執(zhí)行對應用部件的更新,而不必擔心因應用部件提供者因應用無響應(ANR)錯誤而關閉。查閱維基字典應用部件提供者示例了解運行服務的應用部件例子。
接收應用部件廣播意圖
AppWidgetProvider僅是一個便利類。如果你想直接接收應用部件廣播,可以實現(xiàn)自己的BroadcastReceiver或重新實現(xiàn)onReceive(Context, Intent)回掉。你需要考慮的意圖如下:
創(chuàng)建應用部件配置活動
如果你想讓用戶在他或她添加新應用部件時配置設置,可以創(chuàng)建一個應用部件配置活動。這個活動會被應用部件宿主自動啟動并且允許用戶在創(chuàng)建時配置可用設置,例如應用部件顏色,大小,更新間隔或其他功能設置。
配置活動應該在安卓清單文件中聲明一個標準的活動。但是,它會被應用部件宿主使用ACTION_APPWIDGET_CONFIGURE操作啟動,因此該活動需要接受這個意圖。例如:
該活動還必須在AppWidgetProviderInfo的XML文件中使用android:configureattribute屬性聲明(參考添加AppWidgetProviderInfo元數(shù)據(jù))。例如,配置活動可以像這樣聲明:
注意:該活動使用了全路徑名稱空間,因為它將在你的包外面被引用。
這就是所有你要為配置活動準備的東西?,F(xiàn)在你所需要的就是一個實在(確實存在)的活動。但是,在實現(xiàn)你活動時,有兩點重要的事情要記?。?/p>
應用部件宿主調(diào)用配置活動并且配置活動總該返回一個結(jié)果。結(jié)果應該包含啟動該活動意圖傳遞的應用部件ID(保存在意圖額外信息的EXTRA_APPWIDGET_ID(譯者注:就是要用getExtra憑這個ID獲取的數(shù)據(jù),由setExtra設置))。
onUpdate方法在應用部件被創(chuàng)建后不會被調(diào)用(在配置活動啟動時系統(tǒng)不會發(fā)送ACTION_APPWIDGET_UPDATE廣播)。配置活動有責任在應用部件首次創(chuàng)建時向應用部件管理者請求更新。但是,onUpdate方法會被調(diào)用用于后續(xù)的更新——它僅在首次被忽略。
在下面的小節(jié)中的代碼片段會看到如何從該配置返回結(jié)果和更新應用部件的例子。
從配置活動更新應用部件
當應用部件使用配置活動時,該活動有責任在配置完成后更新應用部件。你可以通過向應用部件管理者直接請求更新。
下面是正確更新應用部件和關閉配置活動過程的總結(jié):
提示:當你的配置活動首次打開時,設置活動結(jié)果為RESULT_CANCELED,這樣,在用戶在完成之前退出,應用部件宿主會被通知配置被取消并且應用部件不會被添加。
參考ApiDemos中的Exam示例類為例。
設置預覽圖片
安卓3.0版本引入了previewImage字段,它指定了應用部件看起來什么樣的預覽圖片。該預覽圖片在部件選取器中顯示給用戶。如果沒有提供該字段,應用部件的圖標會被用于預覽圖片。
這顯示了你將如何在XML中指定這些設置:
為了幫助創(chuàng)建應用部件的預覽圖片(在previewImage字段中指定),安卓模擬器中包含了叫“Widget Preview?!钡膽?。要創(chuàng)建預覽圖片,啟動應用,選擇你的應用的應用部件并設置你想讓預覽圖片如何顯現(xiàn),然后保存并將它放在應用的可繪制資源中。
在鎖屏中啟用應用部件
安卓4.2版本引入了能讓用戶將部件添加到鎖屏的能力。在指定AppWidgetProviderInfo的XML文件中聲明android:widgetCategory屬性,來表示可以在鎖屏使用你的應用部件。這個屬性包括了兩個屬性:"home screen"和"keyguard "。應用部件可以聲明支持其中之一或全部。
默認情況下,每個應用部件都支持放置在主屏幕上,因此"home_screen"是android:widgetCategory屬性的默認值。如果你的應用部件可以用于鎖屏,那么添加"keyguard"值:
如果你聲明部件可以同時顯示在鍵盤鎖(鎖屏)和主屏上,那么你可能會想根據(jù)顯示的位置定制這個部件。例如,你可以分別為鎖屏和主屏定義獨立的布局。下一步是在運行時檢測部件的類別并做出相應的回應。你可以調(diào)用getAppWidgetOptions以獲取部件選項的包來檢測部件是在鎖屏上還是在主屏上。返回的包會包含鍵OPTION_APPWIDGET_HOST_CATEGORY,它的值將是WIDGET_CATEGORY_HOME_SCREEN或WIDGET_CATEGORY_KEYGUARD中的一個。該值部件綁定的宿主決定。在應用部件提供者中,那時你可以檢測部件的分類,例如:
一旦你知道了部件的分類,就可以選擇讀取不同的基礎布局,設置不同的屬性,等等。例如:
當部件位于鎖屏時,你還應該用android:initialKeyguardLayout屬性為你的應用部件指定一個初始布局。這與android:initialLayout屬性的工作方式一樣,這種方式提供了一個應用部件初始化后立刻顯示的布局并可以更新該布局。
大小調(diào)整向?qū)?/h4>
當部件由鎖屏托管(3)時,框架會忽略minWidth,minHeight,minResizeWidth,和minResizeHeight字段。如果部件還是個主屏部件,那么還需要這些屬性因為他們?nèi)匀挥糜谥髌聊?,但是他們會在用于鎖屏時被忽略掉。
鎖屏部件的寬度總會填充整個提供的空間。對于鎖屏部件的高度,你有如下選擇:
如果該部件沒有標記自己為可垂直調(diào)節(jié)大?。╝ndroid:resizeMode="vertical"),那么部件高度將總為"small":
在手機的豎直模式中,"small"定義為解鎖界面要顯示時的剩余空間。
在平板和水平模式的手機中,"small"設置在每個設備的基礎上(4)。
如果部件標記自己為可垂直調(diào)節(jié)大小,那么該部件在顯示解鎖界面的水平模式的手機上的高度顯示為"small"。其他所有情況,部件縮放到填充全部有效高度。
為應用部件使用集合(5)
安卓3.0版本為應用部件引入了集合。這些應用部件類型使用RemoteViewsService來顯示由遠端數(shù)據(jù)支持的集合,例如來自內(nèi)容提供者數(shù)據(jù)。由RemoteViewsService提供的數(shù)據(jù)顯示在使用如下視圖類型的應用部件中,我們將稱他們?yōu)椤奔弦晥D:“
ListView 在垂直滾動列表中顯示條目的視圖。舉個例子,看下Gmail應用部件。
GridView 在2唯滾動網(wǎng)格中顯示條目的視圖。舉個例子,看下書簽應用部件。
StackView堆疊卡片視圖(類似名片夾(譯者注:好像一疊撲克,從中抽取一張牌的效果)),用戶可以在這里分別向上或向下翻開前面的卡片看到之前或之后的卡片。例子包括YouTube和書籍應用部件。
AdapterViewFlipper 適配器支持的簡單ViewAnimator,它在兩個以上的視圖間變化。一次僅顯示一個子視圖。
如上所述,這些視圖顯示了由遠端數(shù)據(jù)支持的集合。這意味著他們可以使用適配器將他們的界面綁定到他們的數(shù)據(jù)上。適配器將從一組數(shù)據(jù)中把單獨的條目綁定到單獨的視圖對象中。因為這些集合試圖由適配器支持,安卓框架必須包含額外的架構(gòu)以支持他們在應用部件中的使用。在應用部件的上下文中,適配器被RemoteViewsFactory替換,這是簡單地圍繞適配器接口的輕度包裝。當請求集合中的特定條目時,RemoteViewsFactory創(chuàng)建并返回這個集合條目的RemoteViews對象。為了在應用部件中包含集合視圖,你必須實現(xiàn)RemoteViewsService和RemoteViewsFactory。
RemoteViewsService是允許遠端適配器請求RemoteViews對象的服務。RemoteViewsFactory是集合視圖(例如,ListView,GridView等等)和它的核心數(shù)據(jù)間的適配接口。這是StackView部件示例中你用來實現(xiàn)服務和接口的樣板代碼的例子。
示例應用
本小節(jié)的代碼摘錄是從StackView部件示例中摘出:
這個例子有一疊10個顯示從"0!"到"9!"的視圖構(gòu)成,這個示例應用部件有這些主要行為:
用戶可以劃開(5)應用部件上面的視圖以顯示下一個或上一個視圖。這是一個內(nèi)置的StackView行為。
無需用戶交互,應用部件自動地按順序推進(6)它的視圖,像幻燈片播放一樣。 這是由于res/xml中的android:autoAdvanceViewId="@id/stack_view"的設置。這個設置應用于視圖ID,它在這種情況里代表層疊視圖的視圖ID。
如果用戶點擊上面的視圖,應用部件會顯示Toast消息”點擊了視圖n“這里的n是點擊視圖的序號(位置)。要了解更多這是如何實現(xiàn)的信息,參考給單獨條目添加行為。
實現(xiàn)帶有集合應用部件
要實現(xiàn)帶有集合的應用部件,你要遵循一些將用來實現(xiàn)任何應用部件的基礎步驟。下面的小節(jié)描述了你需要執(zhí)行的另外的步驟用以實現(xiàn)帶有的應用部件。
帶有集合的應用部件的清單文件
除了在清單中聲明應用部件列出的需求之外,要是帶有集合視圖的應用部件綁定到RemoteViewsService成為可能,你必須在清單文件中使用BIND_REMOTEVIEWS權(quán)限聲明服務。這阻止了其他應用隨意訪問你的應用部件數(shù)據(jù)。例如,當創(chuàng)建使用usesRemoteViewsService填充集合視圖的應用部件時,該清單項可能看起來像這樣:
android:name="MyWidgetService"行引用了你的RemoteViewsService類。
帶有集合的應用部件的布局
應用部件布局XML文件的主要需求就是包含這些集合視圖中的一個:ListView,GridView,StackView,或AdapterViewFlipper。下面是StackView部件示例中的widge:
注意空視圖必須是其空視圖代表空狀態(tài)的集合視圖的相鄰視圖(譯者注:這里是描述的是列表里沒數(shù)據(jù)時,屏幕什么都沒有的情況,這是可以為這類集合使用一個空視圖,并列的放一起就行。這里表達的意思是只有集合需要空試圖的時候才能在旁邊放個空視圖。例如,一個只有一個文本”請拖拽刷新“的空視圖。)。
除了整個應用部件的布局文件為,你還必須創(chuàng)建定義了集合中每個條目布局的布局文件(例如數(shù)據(jù)集合中每本書的布局)。例如,既然所有條目都使用相同的布局,StackView 部件示例僅有一個布局文件,widge。但是WeatherListWidget示例有兩個布局文件:dark_widge和light_widge。
帶有集合的應用部件的AppWidgetProvider類
作為一個正常的應用部件,AppWidgetProvider子類中的大部分代碼通常是在onUpdate中。在創(chuàng)建帶有集合的應用部件時,onUpdate實現(xiàn)的主要區(qū)別就是你必須調(diào)用setRemoteAdapter。這告訴集合視圖從哪里獲取數(shù)據(jù)。RemoteViewsService可以在那時返回你的RemoteViewsFactory實現(xiàn),然后應用部件可以提供相應的數(shù)據(jù)。當你調(diào)用這個方法時,必須傳遞指向RemoteViewsService的實現(xiàn)和標明要更新的應用部件的應用部件ID。
例如,下面是StackView部件如何實現(xiàn)onUpdate方法來設置RemoteViewsService為應用部件集合的遠端適配器的:
遠端視圖服務類
數(shù)據(jù)持久化
你依靠服務的單個示例,或任何它所包含的數(shù)據(jù)來持久化。因此,你不應該在RemoteViewsService中保存任何數(shù)據(jù)(除非它是靜態(tài)的)。如果你想應用部件的數(shù)據(jù)持久化,最好的方案是使用一個數(shù)據(jù)持續(xù)超過該進程生命周期的內(nèi)容提供者。
如上所述,RemoteViewsService子類要提供RemoteViewsFactory用以填充集合視圖。
具體來說,你需要執(zhí)行這些步驟:
RemoteViewsService實現(xiàn)的主要內(nèi)容是它的RemoteViewsFactory,如上所述。
遠端視圖工廠接口
實現(xiàn)RemoteViewsFactory接口的自定義類要為應用部件提供集合條目的數(shù)據(jù)。為了做到這點,它結(jié)合了你的應用部件條目XML布局文件和一個數(shù)據(jù)源。這個數(shù)據(jù)源可以是從數(shù)據(jù)庫到簡單的數(shù)組的任何事物。在StackView部件示例中,數(shù)據(jù)源是WidgetItems的數(shù)組。RemoteViewsFactory用作連接數(shù)據(jù)與遠端集合視圖。
有兩個你需要為RemoteViewsFactory子類實現(xiàn)的重要方法是onCreate和getViewAt。
當你首次創(chuàng)建工廠時系統(tǒng)調(diào)用onCreate。這是你創(chuàng)建任何數(shù)據(jù)源的連接和/或游標的地方。例如StackView部件示例使用onCreate初始化一個WidgetItem對象的數(shù)組。當你的應用部件激活時,系統(tǒng)使用他們在數(shù)組中的索引位置來訪問這些對象和它們所包含要顯示的文本。
下面是StackView部件示例中的RemoteViewsFactory實現(xiàn)的摘錄,它顯示了onCreate方法的部分代碼:
RemoteViewsFactory的方法getViewAt返回一個對應于數(shù)據(jù)集中特定位置的數(shù)據(jù)的遠端視圖對象。下面是StackView部件示例中RemoteViewsFactory實現(xiàn)的一段摘錄:
為單獨條目添加行為
上面的小節(jié)為你展示了如何為應用部件集合綁定數(shù)據(jù)。但是如果你想要在集合視圖中為每個單獨的條目動態(tài)的行為要做什么那?
正如使用應用部件提供者類中描述的那樣,你通常要使用setOnClickPendingIntent設置對象的點擊行為——如引發(fā)按鈕啟動一個活動。但這個方案不能用于單獨集合條目(舉例說明,你可以使用setOnClickPendingIntent()在Gmail應用部件中建立一個全局按鈕啟動該應用,但不能用于每個單獨的列表項)的子視圖。相反,你要使用setOnClickFillInIntent來為集合中單獨條目添加點擊行為。這需要為集合視圖建立一個掛起意圖模板,然后通過RemoteViewsFactory為每個集合中的條目設置一個填充意圖。
本節(jié)使用StackView部件示例來描述如何為單獨條目添加行為。在StackView部件示例中,如果你點擊了上面的視圖,應用部件顯示了Toast消息”點擊了視圖n,“這里的n是點擊視圖的索引(位置)。下面描述了它是如何工作的:
注意:StackView部件示例使用了廣播,但是像這樣的情況,應用部件通常會簡單地啟動一個活動。
建立一個掛起意圖模板
StackWidgetProvider (AppWidgetProvider子類)建立一個掛起意圖。單獨的集合條目不能建立他們自己的掛起意圖。相反,集合作為整體建立一個掛起意圖模板,然后單獨條目建立一個填充意圖來創(chuàng)建一個逐條基礎上的獨特行為。
這個類還接收用戶點擊視圖時發(fā)送的廣播。它在onReceive方法中處理這個事件。如果意圖的操作是TOAST_ACTION,那么該應用部件將為當前視圖顯示一個Toast消息。
建立填充意圖
RemoteViewsFactory必須對每個集合條目創(chuàng)建一個填充意圖。這使得區(qū)分單獨的點擊特定條目的操作成為可能。然后填充意圖與掛起意圖模板結(jié)合以決定點擊條目時將要執(zhí)行的最終意圖。
保持集合數(shù)據(jù)的刷新
下面的圖展示了更新發(fā)生時,使用了集合的應用部件中發(fā)生的流程。它展示了應用部件代碼如何與RemoteViewsFactory交互,和你可以如何觸發(fā)更新:
使用集合的應用部件的一個特征是可以提供給用戶最多的最新內(nèi)容的能力。例如,考慮下安卓3.0版本中的Gmail應用部件,它提供給用戶他們的收件箱的快照。要使這個成為可能,你需要能觸發(fā)RemoteViewsFactory和集合視圖以獲取和顯示新的數(shù)據(jù)。通過AppWidgetManager調(diào)用notifyAppWidgetViewDataChanged來實現(xiàn)這點。這個方法導致一個RemoteViewsFactory的onDataSetChanged方法的回掉,它給你獲取新數(shù)據(jù)的機會。注意你可以在onDataSetChanged中同步地執(zhí)行密集型操作。你要保證這個調(diào)用會在元數(shù)據(jù)或視圖數(shù)據(jù)被從RemoteViewsFactory獲取之前完成。另外,你可以在getViewAt方法中執(zhí)行密集型操作。如果這個調(diào)用占用了很長時間,加載視圖(由RemoteViewsFactor的getLoadingView()視圖指定)會被顯示在集合視圖中相應的位置,直到它返回。
譯者注:這里不支持代碼,所以沒有顯示出來。
百度首發(fā)地址:《android中文開發(fā)向?qū)А?/p>
1.《[安卓7怎么設置中文]安卓導航怎么設置中文?》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡信息知識,僅代表作者本人觀點,與本網(wǎng)站無關,侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《[安卓7怎么設置中文]安卓導航怎么設置中文?》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。
3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/keji/3222756.html