Chinese (Traditional) (中文(繁體)) translation by xingshi (you can also view the original English article)
自Android 1.5以來,應用程序小部件使用戶能夠從舒適的主屏幕獲取信息,控制應用程序並執行關鍵任務。
在這個由兩部分組成的系列中,我將向您展示如何通過向Android項目添加應用程序小部件來提供更好的用戶體驗。
在本系列的最後,您將創建壹個小部件:
- 顯示多組數據。
- 當用戶與View該窗口小部件的布局中的特定對象進行交互時,執行唯壹的操作。
- 每當設定的時間段過去時自動更新。
- 用新數據更新以響應用戶交互。
在第壹篇文章中,我們將使用Android Studio的內置工具快速輕松地生成提供任何 Android應用程序小部件所需的所有文件。然後,我們將在此基礎上進行擴展,以創建壹個檢索並顯示數據並響應onClick
事件的小部件。
什麽是應用程序小部件?
應用程序小部件是壹種輕量級的微型應用程序,通常屬於以下類別之壹:
- 信息小部件。顯示重要信息的不可滾動小部件,例如天氣或時鐘小部件。
- 集合小部件。可滾動的小部件,顯示壹系列相關元素,例如來自同壹刊物的照片或文章庫。 集合小部件通常由數據源(例如
Array
數據庫)支持。集合部件必須包含壹個ListView
,GridView
,StackView
,或AdapterViewFlipper
。 - 控件小部件。壹個用作應用程序遠程控制的小部件,允許用戶觸發常用功能,而無需啟動應用程序。 播放音樂的應用程序通常會提供壹個小部件,讓用戶直接從主屏幕播放,暫停和跳過曲目。
- 混合小部件。為什麽只限於壹個類別,何時可以從多個類別挑選元素?請註意,混音和匹配可能會導致用戶體驗混亂,因此為了獲得最佳效果,您應該在設計widget時考慮單壹類別,然後根據需要添加其他類別的元素。 例如,如果您想創建壹個顯示當前天氣預報的小部件,但也允許用戶查看不同日期和地點的預測,那麽您應該創建壹個信息小部件,然後添加必要的控制元素。
除上述功能外,大多數小部件onClick通過啟動其關聯的應用程序來響應事件,類似於應用程序快捷方式,但它們也可以直接訪問該應用程序中的特定內容。
應用程序小部件必須放置在應用程序小部件主機中,最常見的是Android主屏幕,不過也有壹些第三方應用程序小部件主機,例如流行的Nova Launcher和Apex Launcher。
在整個系列中,我會將小部件作為您放置在主屏幕上的壹部分來討論,但如果您對可以將小部件放在鎖屏上的模糊回憶,那麽這不僅僅是壹種美妙的夢!API級別17和20之間,這是可能將小部件在主屏幕或鎖屏。
由於在21級API中棄用了鎖屏小部件,因此在本系列中,我們將僅為主屏幕創建壹個小部件。
為什麽我應該創建壹個應用程序窗口小部件?
為什麽您應該考慮將應用程序小部件添加到最新的Android項目中有幾個原因。
輕松訪問重要信息和功能
小部件允許用戶直接從主屏幕查看應用程序的最重要信息。例如,如果您開發了日歷應用程序,那麽您可以創建壹個小部件來顯示有關用戶下壹次約會的詳細信息。 這比強迫用戶啟動您的應用程序並潛在地導航多個屏幕來檢索相同的信息要方便得多。
如果您開發了壹個控件(或帶有控件元素的混合控件),那麽用戶也可以直接從主屏幕完成任務。繼續我們的日歷示例,您的小部件可能允許用戶創建,編輯和取消約會,甚至可能無需啟動您的應用程序。 這有可能會從您的某些應用程序的最重要任務中刪除多個導航步驟,這只會對用戶體驗產生積極影響!
直接訪問所有應用程序的最重要屏幕
點擊壹個小部件通常會將用戶帶到關聯應用程序的頂層,類似於應用程序的快捷方式。但是,與應用快捷方式不同,小部件可以鏈接到關聯應用程序中的特定區域。 例如,點擊壹個小部件的新郵件接收通知可能會啟動該應用程序,同時已經選擇了新的消息,而點擊創建新的電子郵件可能會直接將它們帶到您的應用程序的ComposeEmail
活動。
通過在窗口小部件的布局中嵌入多個鏈接,您可以方便地輕松訪問所有應用程序的最重要活動。
創建壹個忠誠的,參與的用戶群
隨著整個口袋妖怪圍棋爆發和隨後的下降證明,讓大量人下載您的應用程序並不會自動保證忠誠的用戶群仍然會使用您的應用程序幾天,幾周甚至幾個月。
移動用戶是壹群相當易變的人,隨著您典型Android智能手機或平板電腦上的內存不斷增加,很容易失去跟蹤您設備上安裝的應用的情況。有機會,如果妳現在拿起妳的Android智能手機或平板電腦,並通過應用程序抽屜滑動,那麽妳會發現至少有壹個應用程序,妳完全忘記了。
通過創建壹個展示所有應用程序最有價值信息和功能的小部件,您可以確保每次用戶瀏覽主屏幕時,都會提醒您不僅應用程序存在,而且還提供了壹些精彩的內容。
將App Widget添加到您的項目
即使是最基本的小部件也需要多個類和資源,但是當您使用Android Studio的內置工具創建小部件時,所有這些文件都是為您生成的。由於在開發Android應用程序方面沒有任何意義,所以我們將使用這些工具來開始構建我們的小部件。
應用程序小部件必須始終與底層應用程序綁定,因此請使用您選擇的設置創建壹個新的Android項目。
壹旦Android Studio構建了您的項目,請從Android Studio工具欄中選擇File> New> Widget> AppWidget。這將啟動配置組件菜單,您可以在其中定義壹些小部件的初始設置。

大多數這些選項都是不言自明的,但有壹些值得更詳細地探討。
可調整大小(API 12+)
如果壹個小部件可以調整大小,那麽用戶可以通過長按該小部件然後拖動出現在其輪廓周圍的藍色手柄來增加或減少其在主屏幕上占用的“單元格”數量。
只要有可能,妳應該給妳的小部件水平和垂直調整大小的能力,因為這將幫助妳的小部件適應各種屏幕配置和主屏幕設置。如果用戶的主屏幕顯得雜亂無章,那麽您的小部件可能無法適應主屏幕,除非您的小部件可調整大小。
如果您確實想要創建不可調整大小的窗口小部件,請打開Resizable下拉菜單,然後選擇僅水平,僅垂直或不可調整大小。
最小寬度和高度
最小寬度和高度指定了小部件放置在主屏幕上時最初占用的單元格數量。
對於可調整大小的小部件,這是用戶可以調整小部件大小的最小值,因此您可以使用這些值來防止用戶將小部件縮小到無法使用的程度。
如果您的小部件不能調整大小,那麽最小寬度和高度值是您小部件的永久寬度和高度。
為了增加widget在壹系列主屏幕上的舒適度,建議您不要使用大於4乘4的任何東西來獲取最小寬度和高度值。
盡管主屏幕“單元格”的確切寬度和高度在不同設備之間有所不同,但您可以使用以下公式粗略估算您的Widget將占用多少DPI(每英寸點數):
70 × number of cells -30
例如,如果您的小部件是2 x 3個單元格:
70 x 2 - 30 = 110 70 x 3 - 30 = 180
該小部件將在用戶的主屏幕上占用大約110 x 180 DPI。如果這些值與特定設備單元格的尺寸不壹致,則Android會自動將您的小部件四舍五入到最接近的單元格尺寸。
查看此菜單中的所有選項並進行所需的更改(我堅持使用默認值),然後單擊完成。
Android Studio現在將生成提供基本應用程序窗口小部件所需的所有文件和資源。這個小部件並不完全令人興奮(它基本上只是壹個藍色塊,其中包括跨越它的單詞示例),但它是壹個可以在設備上測試的功能小部件。
測試小部件:
- 在物理Android設備或AVD(Android虛擬設備)上安裝項目。
- 按住主屏幕上的任何空白區域,然後點擊屏幕底部顯示的單詞Widget,啟動Android的Widget Picker。
- 通過Widget Picker滑動,直到找到藍色示例窗口小部件。
- 按下此小部件將其放到主屏幕上。
- 通過按下小部件來輸入調整大小模式,直到出現壹組藍色手柄,然後拖動這些手柄以增加或減少此小部件占用的單元格數量。

在Android虛擬設備上測試您的小部件
瀏覽應用程序小部件文件 這個小部件可能不會那麽做,但它包含了本系列其余部分我們將要處理的所有類和資源,所以讓我們來看看這些文件以及它們在交付應用程序小部件時扮演的角色。
NewAppWidget.java
小部件提供程序是壹個便利類,包含用於通過編程方式通過廣播事件與小部件進行接口的方法。在引擎蓋下,壹個小部件基本上只是壹個BroadcastReceiver
可以響應各種動作的東西,比如用戶在主屏幕上放置壹個新的小部件實例。
最值得註意的是,應用程序小部件提供程序是您定義小部件的生命周期方法的位置,可以調用小部件的每個實例或僅針對特定實例。
雖然我們傾向於將小部件視為用戶在主屏幕上放置壹次的單個實體,但沒有任何東西阻止它們創建同壹小部件的多個實例。也許妳的小部件是可定制的,直到不同的實例可能具有明顯不同的功能,或者用戶可能非常喜歡妳的小部件,以至於他們想要將它們塗抹在主屏幕上!
我們來看看您可以在小部件提供者類中實現的不同生命周期方法:
該onReceive
事件
Android 在指定事件發生時調用onReceive
()註冊的方法BroadcastReceiver
。
您通常不需要手動實現此方法,因為AppWidgetProvider類會自動過濾所有小部件廣播並將操作委托給適當的方法。
onEnabled
事件
onEnabled
()生命周期方法是為了響應而調用的,ACTION_APPWIDGET_ENABLED
當用戶將小部件的第壹個實例添加到主屏幕時廣播該方法。如果用戶創建了兩個小部件實例,則會onEnabled
()針對第壹個實例調用,但不會針對第二個實例。
此生命周期方法是您執行任何設置的位置,只需對所有窗口小部件實例執行壹次設置,例如創建數據庫或設置服務。
請註意,如果用戶從您的設備中刪除了您的小部件的所有實例,然後創建壹個新實例,那麽這將被歸類為第壹個實例,因此該onEnabled() 方法將再次被調用。
onAppWidgetOptionsChanged
事件
這個生命周期方法被調用以響應ACTION_APPWIDGET_OPTIONS_CHANGED
,當創建壹個小部件實例時以及每次部件被調整大小時廣播這個方法。您可以使用此方法根據用戶如何調整窗口大小來顯示或隱藏內容,盡管此回調僅在Android 4.1和更高版本中受支持。
onUpdate
事件
onUpdate()
生命周期方法被調用每次:
- 更新時間間隔已過。
- 用戶執行觸發該
onUpdate()
方法的操作。 - 用戶將小部件的壹個新實例放置在主屏幕上(除非您的小部件包含配置活動,我們將在第二部分中介紹)。
所述onUpdate
()生命周期方法也被稱為響應於ACTION_APPWIDGET_RESTORED
,每當壹個窗口小部件從備份中恢復被廣播。
對於大多數項目來說,該onUpdate
()方法將包含大量的小部件提供程序代碼,尤其是因為它也是註冊小部件的事件處理程序的地方。
onDeleted
事件
每次從App Widget主機中刪除壹個小部件的實例時,都會調用onDeleted
()方法,這會觸發系統的ACTION_APPWIDGET_DELETED
廣播。
onDisabled
事件
這個方法是為了響應ACTION_APPWIDGET_DISABLED
廣播而調用的,當您的widget的最後壹個實例從App Widget主機中移除時發送。例如,如果用戶創建了三個小部件實例,那麽只有在用戶從主屏幕移除第三個和最終實例時才會調用onDisabled
()方法。
在onDisabled
()生命周期的方法,妳應該清理您創建的任何資源onEnabled
(),因此,如果您在建立壹個數據庫,onEnabled
()然後妳會刪除它onDisabled
()。
onRestored
事件
onRestored
()方法在響應時被調用,ACTION_APPWIDGET_RESTORED
每當應用程序窗口小部件的實例從備份中恢復時就會廣播該方法。如果要維護任何持久數據,則需要重寫此方法並將以前AppWidgetIds
的值重新映射到新值,例如:
public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) { } }
如果妳打開Android Studio自動生成的NewAppWidget.java文件,那麽妳會發現它已經包含了壹些這些widget生命周期方法的實現:
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.widget.RemoteViews; //All widgets extend the AppWidgetProvider class// public class NewAppWidget extends AppWidgetProvider { static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { CharSequence widgetText = context.getString(R.string.appwidget_text); //Load the layout resource file into a RemoteViews object// RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget); views.setTextViewText(R.id.appwidget_text, widgetText); //Tell the AppWidgetManager about the updated RemoteViews object// appWidgetManager.updateAppWidget(appWidgetId, views); } //Define the onUpdate lifecycle method// @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { //appWidgetIds is an array of IDs that identifies every instance of your widget, so this //particular onUpdate() method will update all instances of our application widget// for (int appWidgetId : appWidgetIds) { updateAppWidget(context, appWidgetManager, appWidgetId); } } @Override //Define the onEnabled lifecycle method// public void onEnabled(Context context) { //To do// } @Override //Define the onDisabled method// public void onDisabled(Context context) { //To do// } }
小部件布局文件
res/layout/new_app_widget.xml文件定義了我們的小部件的布局,這也是目前只是壹個藍色的背景字例越過它寫的。
為活動創建布局和為小部件創建布局之間的主要區別是小部件布局必須基於RemoteViews
此,因為這允許Android在應用程序之外(即用戶的主屏幕上)顯示布局。
RemoteViews
不支持各種布局View
,因此在構建小部件布局時,僅限於以下類型:
AnalogClock
Button
Chromometer
FrameLayout
GridLayout
ImageButton
ImageView
LinearLayout
ProgressBar
RelativeLayout
TextView
ViewStub
如果您要創建集合小部件,那麽當您的應用程序安裝在Android 3.0及更高版本上時,您還可以使用以下類型:
AdapterViewFlipper
GridView
ListView
StackView
ViewFlipper
上述類的子類和後代Views不支持。
點擊和滑動
為了確保用戶在主屏幕周圍導航時不會意外與小部件進行交互,小部件onClick
僅響應事件。
當用戶通過將其拖動到主屏幕的卸載操作來移除小部件時,例外情況是,在這種情況下,小部件將響應垂直輕掃手勢。但是,由於此交互由Android系統管理,因此您無需擔心在應用程序中實施垂直刷卡支持。
小工具信息文件
res/xml/new_app_widget_info.xml 文件(又稱AppWidgetProviderInfo文件)定義了壹些小部件的性能,其中包括許多妳在Android Studio中的選擇的設置配置組件的菜單,比如妳的widget的最小尺寸以及是否可以放置在鎖屏上。
該配置文件還指定小部件從App Widget更新服務請求新信息的頻率。決定這個頻率需要妳做出壹個棘手的平衡:更長的更新間隔將有助於節省設備的電池,但是將間隔設置得太遠而且妳的小部件可能會顯示明顯過時的信息。
您還應該意識到,系統會喚醒睡眠設備以獲取新信息,因此盡管每半小時更新壹次小部件可能聽起來不會過多,但可能會導致小部件每30分鐘喚醒設備壹次,這是會影響電池的消耗。
如果您打開項目的new_app_widget_info.xml文件,那麽您會看到它已經定義了許多小部件屬性,包括更新間隔。
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="https://schemas.android.com/apk/res/android" //The layout your widget should use when it’s placed on the lockscreen on supported devices// android:initialKeyguardLayout="@layout/new_app_widget" //The layout your widget should use when it’s placed on the homescreen// android:initialLayout="@layout/new_app_widget" //The minimum space your widget consumes, which is also its initial size// android:minHeight="40dp" android:minWidth="40dp" //The drawable that represents your widget in the Widget Picker// android:previewImage="@drawable/example_appwidget_preview" //Whether the widget can be resized horizontally, vertically, or along both axes, on Android 3.1 and higher// android:resizeMode="horizontal|vertical" //How frequently your widget should request new information from the app widget provider// android:updatePeriodMillis="86400000" //Whether the widget can be placed on the homescreen, lockscreen (“keyguard”) or both.// //On Android 5.0 and higher, home_screen is the only valid option// android:widgetCategory="home_screen"></appwidget-provider>
如果妳確實給妳的用戶提供了將妳的小部件放置在鎖屏上的選項,那麽記住小部件的內容對於那些看過鎖屏的人都是可見的。如果您的“默認”布局包含任何個人或潛在的敏感信息,那麽您應該為您的小部件放置在鎖定屏幕上時使用替代布局。
res / values / dimens.xml文件
當它們相互壓在壹起時,或者當它們延伸到主屏幕的邊緣時,小部件看起來並不是最好的。
無論何時在Android 4.0或更高版本上顯示小部件,Android操作系統都會在小部件框架和邊界框之間自動插入壹些填充。

壹個小部件包含壹個邊界框框小部件邊距小部件填充和小部件控件 如果您的應用在運行早於Android 4.0的設備上運行,那麽您的小部件需要自行提供此填充。
當您使用文件>新建>小工具> AppWidget菜單創建小工具時,Android Studio會生成兩個dimens.xml文件,以確保您的小工具始終具有正確的填充,而不管其安裝的Android版本如何。
妳會在妳的項目的res 文件夾中找到這兩個 文件:
res / values / d imens.xml
該文件定義了無論何時安裝在API級別13或更低版本上的小部件需要提供的填充8dpi。
<dimen name="widget_margin">8dp</dimen>
res / values-v14 / dimens.xml
由於Android 4.0及更高版本會自動將填充應用於每個小部件,因此您的小部件提供的任何填充將作為此默認填充的補充。
為了確保您的小部件與用戶放置在主屏幕上的任何應用程序圖標或其他小部件對齊,此dimens.xml文件指定您的小部件應該不會為Android 4.0和更高版本提供額外的頁邊距:
<dimen name="widget_margin">0dp</dimen>
這個默認邊距有助於在主屏幕上進行視覺平衡,所以您應該避免修改它 - 畢竟,您不希望您的小部件成為奇怪的部件!
妳的小部件的布局已經引用了這個尺寸值,(android:padding="@dimen/widget_margin")
所以在處理小部件的布局時要小心不要改變這壹行。
盡管這些dimens.xml文件是確保您的小部件始終具有正確填充的最簡單方法,但如果此技術不適合您的特定項目,那麽壹種替代方法是為API級別14創建具有不同邊距的多個9補丁背景和更高,以及API等級13和更低。 您可以使用Android Studio的Draw 9-patch工具或專用圖形編輯程序(如Adobe Photoshop)創建九個補丁。
項目清單
在您的項目的AndroidManifest.xml文件中,您需要將小部件註冊為BroadcastReceiver
,並指定小部件提供程序和此小部件應使用的AppWidgetProviderInfo文件。
如果您打開清單,您會看到Android Studio已經為您添加了所有這些信息。
//The widget’s AppWidgetProvider; in this instance that’s NewAppWidget.java// <receiver android:name=".NewAppWidget"> <intent-filter> //An intent filter for the android.appwidget.action.APPWIDGET_UPDATE action// <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" //The widget’s AppWidgetProviderInfo object// android:resource="@xml/new_app_widget_info" /> </receiver> </application>
小工具選取器資源
res/drawable/example_appwidget_preview.png 文件是代表了Widget選取器窗口小部件的繪制資源。
為了鼓勵用戶從所有可用的選項中選擇妳的小部件,這個可繪制的應該顯示妳的小部件,在主屏幕上正確配置並顯示大量有用的內容。
當您使用File> New> Widget> AppWidget菜單創建小部件時,Android Studio會自動生成預覽drawable(example_appwidget_preview.png)。
在第二部分中,我將向您展示如何通過使用Android Studio的內置工具來生成您自己的預覽圖像,從而快速輕松地替換此可繪制的存貨。
建立妳的布局
現在我們概述這些文件是如何結合在壹起來創建應用程序小部件的,讓我們在此基礎上進行擴展並創建壹個小部件,它不僅僅是在藍色背景上顯示單詞示例!
我們將為我們的小部件添加以下功能:
-
TextView
顯示Application Widget ID標簽。 -
TextView
檢索並顯示此特定小部件實例的ID。 - 通過啟動用戶的默認瀏覽器並加載
URL
,TextView
來響應onClick事件。
雖然我們可以簡單地TextViews
從Android Studio面板中拖拽三個,然後將它們拖放到畫布上,但如果您的小部件看起來不錯,那麽用戶將更有可能將它放置在主屏幕上,因此,我們要創建壹些資源,以便讓我們的小部件具有更多視覺吸引力。
創建Widget的背景
我將創建壹個帶圓角,漸變背景和邊框的矩形,我將用它作為我的小部件的背景:
- 按住Control鍵並點按您項目的drawable文件夾,然後選擇新建>可繪制資源文件。
- 將該文件命名為widget_background並單擊確定。
- 輸入以下代碼:
<?xml version="1.0" encoding="UTF-8"?> http://schemas.android.com/apk/res/android" android:shape="rectangle"> <stroke android:width="1dp" android:color="#ffffff" /> <gradient android:angle="225" android:endColor="#00FFFFFF" android:startColor="#DD000000" /> <corners android:topRightRadius="10dp" android:topLeftRadius="10dp" android:bottomRightRadius="10dp" android:bottomLeftRadius="10dp" /> </shape>
2.創建TextView
背景
接下來,創建壹個形狀以用作我們的背景TextViews
:
- 按住Control鍵並點按您項目的drawable文件夾,然後選擇新建>可繪制資源文件。
- 將此文件命名為tvbackground,然後單擊確定。
- 輸入以下代碼:
<?xml version="1.0" encoding="utf-8"?> http://schemas.android.com/apk/res/android" android:shape="rectangle" > <stroke android:width="1dp" android:color="#000000" /> <solid android:color="#FFFFFFFF" /> <corners android:topRightRadius="15dp" android:topLeftRadius="15dp" android:bottomRightRadius="15dp" android:bottomLeftRadius="15dp" /> </shape>
3.創建壹些樣式
我也將使用以下樣式:
-
widget_text
。大膽的效果,我將應用到小部件的文本。 -
widget_views
。我將適用於我的各種利潤和填充TextViews
。
打開項目的styles.xml文件並添加以下內容:
<style name="widget_views" parent="@android:style/Widget"> <item name="android:padding">8dp</item> <item name="android:layout_marginTop">12dp</item> <item name="android:layout_marginLeft">12dp</item> <item name="android:layout_marginRight">12dp</item> <item name="android:textStyle">bold</item> </style> <style name="widget_text" parent="@android:style/Widget"> <item name="android:textStyle">bold</item> </style>
4.建立妳的布局!
現在我們所有的資源都已到位,我們可以創建小部件的布局。打開new_app_widget.xml文件並添加以下內容:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="@dimen/widget_margin" android:background="@drawable/widget_background" android:orientation="vertical" > <LinearLayout android:background="@drawable/tvbackground" style="@style/widget_views" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/id_label" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/widget_id" style="@style/widget_text" /> <TextView android:id="@+id/id_value" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="." style="@style/widget_text" /> </LinearLayout> <TextView android:id="@+id/launch_url" style="@style/widget_views" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/URL" android:background="@drawable/tvbackground"/> </LinearLayout>
最後,打開strings.xml文件並定義我們在布局中引用的字符串資源:
<resources> <string name="app_name">Widget</string> <string name="widget_id">App Widget ID\u0020</string> <string name="URL">Tap to launch URL</string> </resources>
通過預覽布局將如何在各種設備上呈現,Android Studio的“ 設計”選項卡可幫助您更高效地工作。每次更改布局時,切換到“ 設計”選項卡比在Android設備上運行項目要容易得多。
令人沮喪的是,Android Studio並沒有提供專門的小部件外觀,所以默認情況下,小部件的布局就像普通的Activity壹樣渲染,這並不能提供有關小部件在用戶主屏幕上的外觀的最佳見解。
壹種潛在的解決方法是使用Android Wear(Square)外觀呈現您的布局,該外觀與Android應用程序窗口小部件的大小和形狀相似:
- 確保Android Studio的設備選項卡已被選中。
- 打開設備下拉菜單。
- 從下拉菜單中選擇280 x 280,hdpi(方形)。

嘗試使用Android Wear Square外觀呈現小部件布局
創建Widget功能。 既然我們的小部件看起來是這個部分,現在是時候給它壹些功能:
- 檢索並顯示數據。每個小部件的實例在添加到App Widget主機時都會分配壹個ID。 該ID在整個小部件的生命周期中保持不變,並且對於該小部件實例而言是完全唯壹的,即使用戶將同壹小部件的多個實例添加到其主屏幕。
- 添加壹個動作。我們將創建壹個
OnClickListener
啟動用戶的默認瀏覽器並加載壹個URL。
打開小部件提供程序文件(NewAppWidget.java)並刪除檢索appwidget_text字符串資源的行:
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { //Delete the following line// CharSequence widgetText = context.getString(R.string.appwidget_text); RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget); views.setTextViewText(R.id.appwidget_text, widgetText); appWidgetManager.updateAppWidget(appWidgetId, views); }
在updateAppWidget
塊中,我們現在需要R.id.id_value
使用小部件的唯壹ID 更新占位符:
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget); views.setTextViewText(R.id.id_value, String.valueOf(appWidgetId));
我們還需要創建壹個Intent對象,其中包含應在用戶與此TextView
交互時加載的URL。
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://code.tutsplus.com/")); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); //Attach an OnClickListener to our “launch_url” button, using setOnClickPendingIntent// views.setOnClickPendingIntent(R.id.launch_url, pendingIntent);
以下是完整的小部件提供程序文件:
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.widget.RemoteViews; import android.app.PendingIntent; import android.content.Intent; import android.net.Uri; public class NewAppWidget extends AppWidgetProvider { static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { //Instantiate the RemoteViews object// RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget); //Update your app’s text, using the setTextViewText method of the RemoteViews class// views.setTextViewText(R.id.id_value, String.valueOf(appWidgetId)); //Register the OnClickListener// Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://code.tutsplus.com/")); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.launch_url, pendingIntent); appWidgetManager.updateAppWidget(appWidgetId, views); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { //Update all instances of this widget// for (int appWidgetId : appWidgetIds) { updateAppWidget(context, appWidgetManager, appWidgetId); } } }
測試Widget
現在是時候把這個小部件進行測試!
- 在Android設備上安裝更新的項目。
- 為確保您看到此小部件的最新版本,請從主屏幕中刪除任何現有的小部件實例。
- 按主屏幕上的任何空白部分,然後從Widget Picker中選擇您的Widget。
- 根據需要重新定位並調整窗口小部件的大小。

把妳的Android應用程序小部件進行測試。 通過選擇點擊啟動URL ,檢查小部件是否響應用戶輸入事件
TextView
。應用程序小部件應通過啟動默認瀏覽器並加載URL來做出響應。
如果您壹直關註本教程,那麽此時您將擁有壹個功能齊全的小部件,可以演示Android應用程序小部件的許多核心概念。您也可以從我們的GitHub倉庫下載完成的項目。
結論
在這篇文章中,我們研究了在構建壹個檢索並顯示壹些唯壹數據並響應用戶輸入事件的小部件之前,交付Android應用程序小部件所需的所有文件。
目前,我們的小部件仍然缺少壹項主要功能:它從不顯示任何新信息!在下壹篇文章中,我們將給這個小部件自動檢索和顯示新數據的能力,基於設定的時間表以及直接響應用戶輸入事件。
同時,在Envato Tuts +上查看壹些關於Android應用程序開發的其他精彩文章!
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post