編輯:關於Android編程
應用Widget是可以在其他應用程序(如主屏幕)嵌入並接受定期更新的微型應用程序的意見。這些觀點在用戶界面被稱為小工具,你可以發布一個與應用的Widget提供商。即能持有其他應用程序的窗口小部件的應用程序組件被稱為應用程序的Widget主機。下面的截圖顯示音樂應用的Widget。
本文介紹了如何使用應用程序的Widget提供者發布應用的Widget。為了創建自己的AppWidgetHZ喎?/kf/ware/vc/" target="_blank" class="keylink">vc3TN0Lnc06bTw9Chsr+8/rXEzNbC26Osx+uyztTE06bTw7XEV2lkZ2V01ve7+qGjPGJyPgo8YnI+Cjxicj4Kyei8xrXEV2lkZ2V0PGJyPgrT0LnYyOe6zsnovMbE47XE06bTw7PM0PK0sL/a0KGyv7z+tcTQxc+io6zH69TEtsG0sL/a0KGyv7z+tcTJ6LzG1rjEz6GjPGJyPgq7+bShPGJyPgo8YnI+Cjxicj4K0qq0tL2o0ru49tOm08OzzNDytLC/2tChsr+8/qOsxPrQ6NKqwvrX49LUz8LM9bz+o7o8YnI+Cjxicj4KPGJyPgpBcHBXaWRnZXRQcm92aWRlckluZm+21M/zPGJyPgrD6Mr21KrK/b7dzqrTptPDtcRXaWRnZXSjrMjn1NpBcHAgV2lkZ2V0tcSyvL7Wo6y4/NDCxrXCyqOs0tS8sEFwcFdpZGdldFByb3ZpZGVywOCho9Xi06a1sdLUWE1MwLS2qNLloaM8YnI+CkFwcFdpZGdldFByb3ZpZGVywOC1xMq1z9Y8YnI+Crao0uW1xLv5sb63vbeoo6zIw8T60tSx4LPM0+vTptPDs8zQ8ndpZGdldL3nw+ajrLv509q547KltcTKwrz+oaPNqLn9y/yjrLWx06bTw7PM0PK1xFdpZGdldLG7uPzQwqOsxvTTw6OsvfvTw7rNyb6z/cT6vavK1bW9ueOypaGjPGJyPgrK0828sry+1jxicj4KtqjS5cHL06bTw7PM0PKy5bz+tcSz9cq8sry+1qOs1NpYTUzW0Lao0uWhozxicj4KtMvN4qOsu7m/ydLUyrXP1tK7uPbTptPDtcRXaWRnZXTF5NbDu+62r6Gj1eLKx9K7uPa/ydGhtcS77ravo6y1sdPDu6e9q8T6tcRXaWRnZXTTptPDs8zQ8qOssqLUytDty/u78sv91NrQ3rjEtLTX98qx06bTw9ChuaS+38no1sOjrMb0tq+hozxicj4KPGJyPgo8YnI+CtLUz8K4973aw+jK9sHLyOe6zsno1sPV4tCp1+m8/qGjPGJyPgo8YnI+Cjxicj4K1NrH5bWl1tDJ+cP30ru49tOm08OzzNDytLC/2tChsr+8/jxicj4KPGJyPgo8YnI+CsrXz8ijrMn5w/fU2tOm08OzzNDytcRBbmRyPz9vaWRNYW5pZmVzdC54bWzOxLz+1tC1xEFwcFdpZGdldFByb3ZpZGVywOCho8D9yOejujxicj4KPC9wPgo8cD48L3A+CjxwcmUgY2xhc3M9"brush:java;">
在<意向filter>元素必須包含了Android的元素:name屬性。該屬性指定AppWidgetProvider接受ACTION_APPWIDGET_UPDATE播出。這是你必須顯式聲明的唯一播出。該AppWidgetManager自動發送所有其他App的Widget廣播到AppWidgetProvider是必要的。
在<元數據>元素指定AppWidgetProviderInfo資源,需要以下屬性:
機器人:名字 - 指定的元數據名稱。使用android.appwidget.provider標識數據作為AppWidgetProviderInfo描述符。
機器人:資源 - 指定AppWidgetProviderInfo資源位置。
添加AppWidgetProviderInfo元
該AppWidgetProviderInfo一個App Widget時,基本素質定義,如最小尺寸的布局,其初始布局資源,多久更新應用程序窗口小部件,和(可選)配置活動在創建時推出。定義AppWidgetProviderInfo對象使用一個元素的XML資源,並將其保存在項目的RES / XML /文件夾。
例如:
這裡的的摘要屬性:
<frameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:padding="@dimen/widget_margin">創建兩個維度的資源,一個在RES/價值/提供預Android 4.0的定制空間,和一個在res/值-V14/提供Android 4.0的小部件沒有微胖:… </frameLayout>
res/values-v14/dimens.xml:8dp
另一種選擇是簡單地在默認情況下建造額外的利潤到您的九宮背景的資產,並提供不同的九補丁沒有利潤率API級別14或更高版本。0dp
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這AppWidgetProvider定義了用於定義啟動一個活動的PendingIntent,並與setOnClickPendingIntent(INT,的PendingIntent)連接到App Widget的按鈕的目的只有的onUpdate()方法。請注意,它包含一個循環,通過appWidgetIds每個條目,這是確定此提供程序創建的每個應用程序的Widget ID數組進行迭代。以這種方式,如果用戶創建的應用程序的widget的多個實例,則它們都同時更新。但是,只有一個updatePeriodMillis時間表將用於應用程序的widget的所有實例進行管理。例如,如果更新時間表被定義為每兩個小時,和App小工具的第二個實例是第一個之後添加一小時後,他們都將在由第一和第二更新所定義的周期來更新期間將被忽略(他們都會進行每兩小時不每小時更新一次)。
注意:因為AppWidgetProvider是廣播接收器的擴展,你的進程不能保證繼續運行,回調方法返回後(見的BroadcastReceiver關於廣播生命周期信息)。如果你的應用的Widget安裝過程可能需要幾秒鐘(也許當執行網頁請求),你需要你的進程繼續,考慮在的onUpdate()方法啟動服務。從服務中,您可以不用擔心AppWidgetProvider收盤下跌,由於應用程序執行自己的更新到App控件不響應(ANR)錯誤。參見維基樣品的AppWidgetProvider運行服務一個App的Widget的例子。
另請參閱ExampleAppWidgetProvider.java示例類。
接收應用的Widget廣播意圖
AppWidgetProvider只是一個方便的類。如果您想直接接收應用的Widget廣播,你可以實現自己的BroadcastReceiver或者重寫的onReceive(上下文,意圖)回調。你需要關心的意圖如下:
ACTION_APPWIDGET_UPDATE
ACTION_APPWIDGET_DELETED
ACTION_APPWIDGET_ENABLED
ACTION_APPWIDGET_DISABLED
ACTION_APPWIDGET_OPTIONS_CHANGED
創建應用程序窗口小部件配置活動
如果您想用戶配置設置時,他或她增加了一個新的Widget應用程序,你可以創建一個應用程序的Widget配置活動。本次活動將通過應用程序的Widget主機自動啟動,並允許用戶在配置創建時間為App的Widget可用的設置,如應用程序的Widget顏色,尺寸,更新周期或其他功能的設置。
配置活動應該被聲明為Android清單文件中的正常活動。但是,它將被應用的Widget主機與ACTION_APPWIDGET_CONFIGURE行動推出,所以活動需要接受這個意圖。例如
(見添加AppWidgetProviderInfo元以上)配置屬性:此外,活動必須在AppWidgetProviderInfo XML文件中聲明,與Android。例如,配置活動可以聲明如下:
請注意,該活動是聲明的完全限定的命名空間,因為它會從你的包范圍內引用。
這就是所有你需要開始使用的配置活動。現在,所有你需要的是實際的活動。有,但是,當你實現了活動的兩個重要的事情要記住:
該應用程序的Widget宿主調用配置活動以及配置活動應該總是返回一個結果。結果應該包括由發起的活動(保存在Intent作為額外EXTRA APPWIDGETID)的意圖傳遞的應用程序窗口小部件ID。
在創建應用程序窗口小部件時(當配置活動推出的系統將不會發送ACTION APPWIDGET_UPDATE廣播)的的onUpdate()方法將不會被調用。它是配置活動的責任從AppWidgetManager請求更新第一次創建應用程序窗口小部件時。然而,的onUpdate()將被要求對後續更新,它只是跳過第一次。
請參閱下一節的代碼片段如何從配置返回結果和更新應用的Widget的例子。
從配置活動更新應用的Widget
當一個應用程序的Widget使用配置的活動,這是活動的責任來更新應用程序窗口小部件時配置完成。您可以直接從AppWidgetManager請求更新這麼做。
下面就來正確地更新應用程序窗口小部件並關閉配置活動的程序的摘要:
首先,獲得從發射活動的意圖應用的Widget ID:
Intent intent = getIntent(); Bundle extras = intent.getExtras(); if (extras != null) { mAppWidgetId = extras.getInt( AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); }執行你的App小部件配置。
當配置完成後,通過調用的getInstance(上下文)獲得AppWidgetManager的實例:
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);Update the App Widget with aRemoteViews
layout by callingupdateAppWidget(int, RemoteViews)
:
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget); appWidgetManager.updateAppWidget(mAppWidgetId, views);
- Finally, create the return Intent, set it with the Activity result, and finish the Activity:
Intent resultValue = new Intent(); resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); setResult(RESULT_OK, resultValue); finish();提示:當您的配置活動第一次打開,設置活動結果RESULT_CANCELED。這樣一來,如果用戶備份出活動的到達結束之前,應用的Widget通知主機的配置被取消和App的Widget將不能添加。
見ApiDemos的ExampleAppWidgetConfigure.java示例類的例子。
設置預覽圖像
Android 3.0的推出previewImage領域,它指定什麼樣的應用程序窗口小部件看起來像一個預覽。此預覽被示出為從微件選擇器的用戶。如果沒有提供這個領域,應用Widget的圖標用於預覽。
這是你如何指定XML此設置
為了幫助您的應用程序窗口小部件(指定預覽圖像場)創建一個預覽圖像,Android模擬器包括稱為應用程序“窗口小部件預覽”。要創建一個預覽圖像,啟動這個應用程序,選擇您的應用程序應用程序窗口小部件,並將它設置你喜歡你們的預覽圖像出現,然後將其保存,並將其放置在應用程序的繪圖資源。
使用App窗口小部件與收藏
Android 3.0的推出應用小部件與集合。這些種類的應用程序的窗口小部件的使用RemoteViewsService來顯示由遙控數據,如從內容提供商備份集合。由RemoteViewsService提供的數據呈現在使用下面的視圖類型,我們將把為一體的應用程序部件“收集的意見:”
列表顯示
這顯示了垂直滾動列表項的視圖。舉一個例子,看看Gmail應用程序部件。
網格視圖
這顯示了在二維滾動網格項目的視圖。舉一個例子,看到書簽應用部件。
StackView
一種堆疊卡片視圖(有點像一個關系網,),在這裡用戶可以輕彈前卡上/下看到一個/下一個卡,分別為。例子包括YouTube和圖書應用的部件。
AdapterViewFlipper
適配器支持簡單ViewAnimator兩個或多個視圖之間動畫。只有一個孩子,顯示在一段時間。
如上所述,這些收集的意見顯示由遠程數據支持的集合。這意味著,他們使用適配器將其用戶界面綁定到他們的數據。適配器結合從一組數據成單個視圖對象的單個項目。由於這些收集的意見是通過適配器支持,Android框架必須包括額外的架構,支持應用小部件的使用。在一個應用程序widget的背景下,適配器是由RemoteViewsFactory,這簡直就是圍繞適配器接口的瘦包裝所取代。當集合中要求特定項目時,RemoteViewsFactory創建並返回該項目的集合作為一個RemoteViews對象。為了在您的應用程序窗口小部件集合視圖,您必須實現RemoteViewsService和RemoteViewsFactory。
RemoteViewsService是一種服務,它允許遠程適配器請求RemoteViews對象。 RemoteViewsFactory是一個集合視圖之間的適配器,該視圖的基礎數據的接口(如ListView中,GridView的,等等)和。從StackView的Widget樣本,這裡是你用來實現這個服務和接口的樣板代碼的例子:
public class StackWidgetService extends RemoteViewsService { @Override public RemoteViewsFactory onGetViewFactory(Intent intent) { return new StackRemoteViewsFactory(this.getApplicationContext(), intent); } } class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { //... include adapter-like methods here. See the StackView Widget sample. }示例應用程序
本節中的代碼摘錄從StackView控件樣品得出:
該樣本包括10次,其中顯示值棧的“0”!到“9”!示例應用程序部件有這些主要行為:
用戶可以垂直甩在應用程序插件的頂視圖來顯示一個或下一個視圖。這是一個內置StackView行為。
無需任何用戶交互,應用小工具會自動通過其在序列意見的進步,像幻燈片。這是由於設置的android:在res / XML / stackwidgetinfo.xml文件autoAdvanceViewId =“@ ID / stack_view”。此設置適用於該視圖的ID,在這種情況下是堆棧視圖的視圖ID。
如果用戶觸摸的頂視圖,該應用插件播放吐司消息“已觸摸視圖N,”,其中n是被觸摸的視圖的索引(位置)。對於這是如何實現的更多討論,請參見添加行為的個別項目。
實施與應用的集合小工具
為了實現與集合的應用程序插件,你按照你會用它來實現任何應用程序插件的相同的基本步驟。以下各節介紹您需要執行來實現與集合的應用程序插件的額外步驟。
清單與集合應用小工具
除了聲明中的清單應用程序窗口小部件列出的要求,使其能夠用於收藏的應用程序部件綁定到你的RemoteViewsService,您必須在使用許可BIND_REMOTEVIEWS您的清單文件中聲明該服務。這可以防止其他應用程序訪問任意你的應用程序widget的數據。例如,創建一個使用RemoteViewsService來填充集合視圖一個App窗口小部件時,清單條目可能是這樣的:
該生產線機器人:名字=“MyWidgetService”指的是你RemoteViewsService的子類。
布局與集合應用小工具
為您的應用程序部件的布局XML文件的主要要求是,它包括收集意見之一:ListView中,GridView控件,StackView或AdapterViewFlipper。下面是StackView樣品的Widget小部件layout.xml:
<frameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">需要注意的是空的意見必須是其空視圖表示空狀態集合視圖的兄弟姐妹。</frameLayout>
除了布局文件為您的整個應用程序窗口小部件,您必須創建定義布局集合中的每個項目另一個布局文件(例如,每本書的藏書在布局)。例如,StackView的Widget樣品僅具有一個布局文件,widget_item.xml,由於所有的項目使用相同的布局。但是WeatherListWidget樣品有兩個布局文件:dark_widget_item.xml和light_widget_item.xml。
對於集合應用小部件AppWidgetProvider類
與普通的應用小工具,在你的AppWidgetProvider子類的大量代碼通常進去的onUpdate()。在實施的onUpdate的主要區別創建帶有集合一個應用程序窗口小部件時()是你必須調用setRemoteAdapter()。這告訴集合視圖從哪裡得到它的數據。然後RemoteViewsService可以回到你的RemoteViewsFactory實施,和小部件能容納相應的數據。當你調用這個方法,你必須通過一個指向您的實現RemoteViewsService,並指定應用程序窗口小部件更新的應用小部件ID的意圖。
例如,這裡的StackView的Widget樣本是如何實現的onUpdate()回調方法來設置RemoteViewsService為應用程序部件集合遠程適配器:
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // update each of the app widgets with the remote adapter for (int i = 0; i < appWidgetIds.length; ++i) { // Set up the intent that starts the StackViewService, which will // provide the views for this collection. Intent intent = new Intent(context, StackWidgetService.class); // Add the app widget ID to the intent extras. intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); // Instantiate the RemoteViews object for the app widget layout. RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout); // Set up the RemoteViews object to use a RemoteViews adapter. // This adapter connects // to a RemoteViewsService through the specified intent. // This is how you populate the data. rv.setRemoteAdapter(appWidgetIds[i], R.id.stack_view, intent); // The empty view is displayed when the collection has no items. // It should be in the same layout used to instantiate the RemoteViews // object above. rv.setEmptyView(R.id.stack_view, R.id.empty_view); // // Do additional processing specific to this app widget... // appWidgetManager.updateAppWidget(appWidgetIds[i], rv); } super.onUpdate(context, appWidgetManager, appWidgetIds); }RemoteViewsService類
堅持數據
你不能靠你的服務,或者包含任何數據的單個實例,堅持。因此,應該沒有任何數據存儲在您的RemoteViewsService(除非它是靜態的)。如果你希望你的應用程序widget的數據依然存在,最好的辦法是使用的ContentProvider其數據持續超過流程生命周期。
如上所述,你RemoteViewsService子類提供用於填充遠程集合視圖的RemoteViewsFactory。
具體來說,您需要執行以下步驟:
子類RemoteViewsService。 RemoteViewsService是通過一個遠程適配器可以請求RemoteViews服務。
在RemoteViewsService子類,包括實現RemoteViewsFactory接口的類。 RemoteViewsFactory為遠程集合視圖之間的適配器該視圖的基礎數據的接口(如ListView中,GridView的,等等),並。你的實現是負責制定一個RemoteViews對象數據集中的每個項目。這個接口是圍繞適配器瘦包裝。
所述RemoteViewsService執行情況的主要內容是其RemoteViewsFactory,如下所述。
RemoteViewsFactory接口
實現RemoteViewsFactory界面自定義類提供了其集合中的項目的數據應用程序部件。要做到這一點,它結合了您的應用程序部件項目XML布局文件與數據源。數據的這個源可以是來自一個數據庫的任何一個簡單陣列。在StackView的Widget樣本,所述數據源是WidgetItems的陣列。該RemoteViewsFactory用作適配器連接到數據膠水遠程采集視圖。
你需要實現你的RemoteViewsFactory子類的兩個最重要的方法是的onCreate()和getViewAt()。
系統調用的onCreate創建工廠的第一次時,()。這是你設置的任何連接和/或光標到數據源。例如,StackView的Widget示例使用的onCreate()來初始化WidgetItem對象的數組。當你的應用程序widget是積極的,系統訪問這些對象使用數組和它們所包含的文本中的索引位置顯示
下面是從StackView的Widget樣品的RemoteViewsFactory實施,顯示了onCreate()方法的部分摘錄:
class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { private static final int mCount = 10; private List所述RemoteViews工廠方法getView()返回在數據集中的指定位置相對應的數據的RemoteViews對象。下面是從StackView的Widget樣品的RemoteViewsFactory實現的摘錄:mWidgetItems = new ArrayList (); private Context mContext; private int mAppWidgetId; public StackRemoteViewsFactory(Context context, Intent intent) { mContext = context; mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); } public void onCreate() { // In onCreate() you setup any connections / cursors to your data source. Heavy lifting, // for example downloading or creating content etc, should be deferred to onDataSetChanged() // or getViewAt(). Taking more than 20 seconds in this call will result in an ANR. for (int i = 0; i < mCount; i++) { mWidgetItems.add(new WidgetItem(i + "!")); } ... } ...
public RemoteViews getViewAt(int position) { // Construct a remote views item based on the app widget item XML file, // and set the text based on the position. RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item); rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).text); ... // Return the remote views object. return rv; }添加行為,個別項目
上述部分介紹如何將數據綁定到你的應用程序窗口小部件的集合。但是,如果你想做的動態行為添加到您的收藏視圖中的單個項目?
如使用AppWidgetProvider類描述,通常使用setOnClickPendingIntent()來設置對象的點擊行為,如造成一個按鈕啟動一個活動。但是,這種做法是不允許在單獨的一個集合項目??子視圖(澄清,你可以使用setOnClickPendingIntent()設置在啟動應用程序,例如Gmail應用程序部件一個全球性的按鈕,但不是各列表項)。相反,添加一個集合中點擊行為向單個項目,您使用setOnClickFillInIntent()。這就需要建立一個未決的意圖模板您的收藏視圖,然後對每個項目集合中通過您的RemoteViewsFactory設置填充的意圖。
本節使用的Widget StackView樣本來描述如何添加行為的個別項目。在StackView的Widget樣品,如果用戶觸摸的頂視圖,該應用插件播放吐司消息“已觸摸視圖N,”,其中n是被觸摸的視圖的索引(位置)。這是它的工作原理:
該StackWidgetProvider(一個AppWidgetProvider子類)創建待意圖有一個名為TOAST_ACTION自定義操作。
當用戶觸摸視圖,意圖被觸發,它廣播TOAST_ACTION。
此廣播是由StackWidgetProvider的的onReceive()方法攔截,以及應用程序插件播放了感動視圖敬酒消息。對於集合的項目中的數據是由RemoteViewsFactory經由RemoteViewsService提供。
注:StackView的Widget示例使用廣播,但通常一個應用程序窗口小部件只會在類似這樣的情況下推出的一項活動。
設置掛起意圖模板
該StackWidgetProvider(AppWidgetProvider子類)建立了一個懸而未決的意圖。集合個人物品不能建立自己的未決意圖。取而代之的是,集合作為一個整體設置了一個待處理的意圖模板,並且單個項目設置填充在意圖上創建一個項目逐個項目基礎的獨特的行為。
這個類還接收當用戶觸摸一個觀點,即發送廣播。它在它的onR??eceive()方法處理此事件。如果意圖的行動是TOAST_ACTION,應用程序插件播放當前視圖敬酒消息
public class StackWidgetProvider extends AppWidgetProvider { public static final String TOAST_ACTION = "com.example.android.stackwidget.TOAST_ACTION"; public static final String EXTRA_ITEM = "com.example.android.stackwidget.EXTRA_ITEM"; ... // Called when the BroadcastReceiver receives an Intent broadcast. // Checks to see whether the intent's action is TOAST_ACTION. If it is, the app widget // displays a Toast message for the current item. @Override public void onReceive(Context context, Intent intent) { AppWidgetManager mgr = AppWidgetManager.getInstance(context); if (intent.getAction().equals(TOAST_ACTION)) { int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); int viewIndex = intent.getIntExtra(EXTRA_ITEM, 0); Toast.makeText(context, "Touched view " + viewIndex, Toast.LENGTH_SHORT).show(); } super.onReceive(context, intent); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // update each of the app widgets with the remote adapter for (int i = 0; i < appWidgetIds.length; ++i) { // Sets up the intent that points to the StackViewService that will // provide the views for this collection. Intent intent = new Intent(context, StackWidgetService.class); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); // When intents are compared, the extras are ignored, so we need to embed the extras // into the data so that the extras will not be ignored. intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout); rv.setRemoteAdapter(appWidgetIds[i], R.id.stack_view, intent); // The empty view is displayed when the collection has no items. It should be a sibling // of the collection view. rv.setEmptyView(R.id.stack_view, R.id.empty_view); // This section makes it possible for items to have individualized behavior. // It does this by setting up a pending intent template. Individuals items of a collection // cannot set up their own pending intents. Instead, the collection as a whole sets // up a pending intent template, and the individual items set a fillInIntent // to create unique behavior on an item-by-item basis. Intent toastIntent = new Intent(context, StackWidgetProvider.class); // Set the action for the intent. // When the user touches a particular view, it will have the effect of // broadcasting TOAST_ACTION. toastIntent.setAction(StackWidgetProvider.TOAST_ACTION); toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent, PendingIntent.FLAG_UPDATE_CURRENT); rv.setPendingIntentTemplate(R.id.stack_view, toastPendingIntent); appWidgetManager.updateAppWidget(appWidgetIds[i], rv); } super.onUpdate(context, appWidgetManager, appWidgetIds); } }設置填充式意圖
您RemoteViewsFactory必須在集合中的每個項目設定一個填空題意圖。這使得可以區分個體上點擊特定項目的動作。在填充在意圖然後,以確定被點擊的項目時,將要執行的最終意圖與的PendingIntent模板相結合。
public class StackWidgetService extends RemoteViewsService { @Override public RemoteViewsFactory onGetViewFactory(Intent intent) { return new StackRemoteViewsFactory(this.getApplicationContext(), intent); } } class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { private static final int mCount = 10; private List保持收集數據新鮮mWidgetItems = new ArrayList (); private Context mContext; private int mAppWidgetId; public StackRemoteViewsFactory(Context context, Intent intent) { mContext = context; mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); } // Initialize the data set. public void onCreate() { // In onCreate() you set up any connections / cursors to your data source. Heavy lifting, // for example downloading or creating content etc, should be deferred to onDataSetChanged() // or getViewAt(). Taking more than 20 seconds in this call will result in an ANR. for (int i = 0; i < mCount; i++) { mWidgetItems.add(new WidgetItem(i + "!")); } ... } ... // Given the position (index) of a WidgetItem in the array, use the item's text value in // combination with the app widget item XML file to construct a RemoteViews object. public RemoteViews getViewAt(int position) { // position will always range from 0 to getCount() - 1. // Construct a RemoteViews item based on the app widget item XML file, and set the // text based on the position. RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item); rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).text); // Next, set a fill-intent, which will be used to fill in the pending intent template // that is set on the collection view in StackWidgetProvider. Bundle extras = new Bundle(); extras.putInt(StackWidgetProvider.EXTRA_ITEM, position); Intent fillInIntent = new Intent(); fillInIntent.putExtras(extras); // Make it possible to distinguish the individual on-click // action of a given item rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent); ... // Return the RemoteViews object. return rv; } ... }
下圖說明了發生在更新時使用集合的應用程序插件的流量。它顯示了應用程序部件代碼如何與RemoteViewsFactory互動,以及如何觸發更新
使用集合應用小部件的一個特點是,為用戶提供了最新的內容。例如,考慮到Android 3.0的Gmail應用小工具,它為用戶提供他們的收件箱的快照。要做到這一點,你需要能夠觸發RemoteViewsFactory和收集,以獲取並顯示新的數據。您的通話AppWidgetManager實現這一notifyAppWidgetViewDataChanged()。此調用生成一個回調到您RemoteViewsFactory的onDataSetChanged()方法,它讓你有機會獲取任何新數據。請注意,您可以內onDataSetChanged()回調同步執行處理密集型操作。你保證,之前的元數據或顯示數據是從RemoteViewsFactory獲取此調用將完成。此外,可以將getViewAt()方法中進行處理密集型操作。如果該調用需要很長的時間,加載視圖(由RemoteViewsFactory的getLoadingView()方法指定),將顯示在集合視圖,直到它返回的相應位置。
整個布局將觸發的方法如下:點擊TextView1 時,執行循環一次後。最後方法將不再向下傳遞。直接交個 Activity執行04-28 16:22:09.509: I/S
項目地址:https://github.com/wlkdb/GA_network_info點擊打開鏈接1、整個app分為android客戶端、java服務端和數據層,客戶
1.簡介其實這個效果幾天之前就寫了,但是一直沒有更新博客,本來想著把芝麻分雷達圖也做好再發博客的,然後今天看到鴻洋的微信公眾號有朋友發了芝麻分的雷達圖,所以就算了,算是一
前言用scrollTo()和scrollBy()方法實現了View的滑動,但是實現的效果非常的生硬,用戶體驗很差。這一篇繼續在原有基礎上,擴展下View的彈性滑動。下面詳