專欄作者新書出版:Android App程式開發剖析 第三版(適用Android 8 Oreo與Android Studio 3)
Android 6 Tutorial 第五堂(2)系統通知服務 – Notification << 前情
一般個人電腦或行動裝置的作業系統,可以在桌面上放置應用程式的捷徑,使用明顯的圖示和應用程式的名稱,讓使用者在桌面上直接啟動常用的應用程式。一些使用者經常操作的功能,例如開啟或關閉裝置的網路或藍牙設備,如果可以不用啟動這些設定的應用程式,使用者就可以在桌面上直接操作這些功能,那應該會比較方便一些。
Android平台提供一種特別的元件「AppWidget」,它可以讓使用者在桌面上直接瀏覽資料,或是執行一些簡單的操作。例如在桌面上顯示時間、行事曆或氣候資訊,這種元件通常會把它稱為「小工具」元件。
這一章介紹設計AppWidget元件的作法,它的設計方式跟其它元件很不一樣。完成這一章的工作以後,為記事應用程式加入新的小工具元件。使用者在畫面長按以後,Android會開啟這樣的畫面,選擇「小工具」:
在選擇小工具的畫面,找到為記事應用應用程式設計好的元件,長按以後把它放到畫面指定的位置:
決定小工具的位置以後,元件自動開啟選擇記事的畫面,選擇其中一個記事項目:
畫面上就會放置一個顯示記事標題的小工具元件:
依照同樣的步驟,可以在畫面加入其它顯示記事標題的小工具:
17-1 加入小工具元件
現在開始為記事應用程式加入小工具元件。啟動Android Studio與記事應用程式以後,在「app」目錄上按滑鼠右鍵 -> 選擇「New -> Widget -> AppWidget」,依照下列的說明輸入需要的資訊:
- Class Name 輸入「ItemAppWidget」。
- Placement 選擇「Home-screen only」。
- Resizable(API 12+) 選擇「Not resizable」。
- Minimum Width (cells) 選擇「4」。
- Minimum Heigth (cells) 選擇「1」。
- 勾選「Configuration Screen」。
完成後選擇「Finish」按鈕:
Android Studio會建立許多小工具元件需要的程式碼與設定檔:
- ItemAppWidget.java :小工具元件類別。
- ItemAppWidgetConfigureActivity.java :小工具設定元件類別,選擇記事項目。
- res/layout/itemappwidget.xml :小工具元件使用的畫面資源。
- res/layout/itemappwidget_configure.xml :小工具設定元件使用的畫面資源。
- res/xml/itemappwidget_info.xml :小工具專用的設定檔。
- res/drawable-nodpi/exampleappwidgetpreview.png :在小工具選擇畫面顯示的縮圖。
- AndroidManifest.xml :自動加入小工具元件與小工具設定元件的設定。
17-2 實作小工具設定元件
使用者選擇記事小工具以後,必須先啟動選擇記事項目元件。小工具元件在專用的設定檔可以設定這個功能,開啟「res/xml/item_app_widget_info.xml」,檢視裡面的內容:
<?xml version="1.0" encoding="utf-8"?>
<!--
android:previewImage:縮圖
android:initialLayout:小工具元件使用的畫面資源
android:configure:小工具設定元件類別
-->
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:configure="net.macdidi.myandroidtutorial.ItemAppWidgetConfigureActivity"
android:initialKeyguardLayout="@layout/item_app_widget"
android:initialLayout="@layout/item_app_widget"
android:minHeight="40dp"
android:minWidth="250dp"
android:previewImage="@drawable/example_appwidget_preview"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen"></appwidget-provider>
Android Studio會自動產生預設的設定元件與畫面資源,這個設定元件可以重複使用主畫面元件的畫面資源,所以刪除在「res/layout」下的「itemappwidget_configure.xml」。接下來開啟「ItemAppWidgetConfigureActivity.java」,修改類別中的欄位宣告:
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
private static final String PREFS_NAME =
"net.macdidi.myandroidtutorial.ItemAppWidget";
private static final String PREF_PREFIX_KEY = "appwidget_";
// 選擇小工具使用的記事項目
private ListView item_list;
private ItemAdapter itemAdapter;
private List<Item> items;
private ItemDAO itemDAO;
同樣在「ItemAppWidgetConfigureActivity.java」,加入下列的方法宣告:
// 選擇記事項目
AdapterView.OnItemClickListener itemListener =
new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
final Context context = ItemAppWidgetConfigureActivity.this;
// 讀取與儲存選擇的記事物件
Item item = itemAdapter.getItem(position);
saveItemPref(context, mAppWidgetId, item.getId());
AppWidgetManager appWidgetManager =
AppWidgetManager.getInstance(context);
ItemAppWidget.updateAppWidget(
context, appWidgetManager, mAppWidgetId);
Intent resultValue = new Intent();
resultValue.putExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
};
// 儲存選擇的記事編號
static void saveItemPref(Context context, int appWidgetId, long id) {
SharedPreferences.Editor prefs =
context.getSharedPreferences(PREFS_NAME, 0).edit();
prefs.putLong(PREF_PREFIX_KEY + appWidgetId, id);
prefs.commit();
}
// 讀取記事編號
static long loadItemPref(Context context, int appWidgetId) {
SharedPreferences prefs =
context.getSharedPreferences(PREFS_NAME, 0);
long idValue = prefs.getLong(PREF_PREFIX_KEY + appWidgetId, 0);
return idValue;
}
// 刪除記事編號
static void deleteItemPref(Context context, int appWidgetId) {
SharedPreferences.Editor prefs =
context.getSharedPreferences(PREFS_NAME, 0).edit();
prefs.remove(PREF_PREFIX_KEY + appWidgetId);
prefs.commit();
}
同樣在「ItemAppWidgetConfigureActivity.java」,找到「onCreate」方法,依照下面的內容修改程式碼:
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setResult(RESULT_CANCELED);
// 改為使用應用程式主畫面
setContentView(R.layout.activity_main);
// 建立與設定選擇小工具使用的記事項目需要的物件
item_list = (ListView)findViewById(R.id.item_list);
itemDAO = new ItemDAO(getApplicationContext());
items = itemDAO.getAll();
itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
item_list.setAdapter(itemAdapter);
item_list.setOnItemClickListener(itemListener);
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
return;
}
}
移除其它在建立小工具的時候預設加入的程式碼。
17-3 實作小工具元件
接下來修改預設的小工具元件類別與畫面資源。開啟「res/layout/item_app_widget.xml」,這是小工具元件使用的畫面資源,決定小工具在畫面上的樣子。依照下面的內容修改它的設定:
<!-- 修改背景 -->
<RelativeLayout 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/item_drawable">
<!-- 修改文字、大小、顏色與刪除背景 -->
<TextView
android:id="@+id/appwidget_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="#000000"
android:textSize="16sp"
android:textStyle="bold|italic"
android:layout_margin="8dp"
android:contentDescription="@string/app_name" />
</RelativeLayout>
開啟小工具元件類別「ItemAppWidget.java」,找到「onDeleted」方法,依照下面的內容修改程式碼:
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
// 刪除小工具已經儲存的記事編號
ItemAppWidgetConfigureActivity.deleteItemPref(
context, appWidgetIds[i]);
}
}
同樣在「ItemAppWidget.java」,找到「updateAppWidget」方法,依照下面的內容修改程式碼:
static void updateAppWidget(Context context,
AppWidgetManager appWidgetManager,
int appWidgetId) {
// 讀取小工具儲存的記事編號
long id = ItemAppWidgetConfigureActivity.loadItemPref(
context, appWidgetId);
// 建立小工具畫面元件
RemoteViews views = new RemoteViews(
context.getPackageName(), R.layout.item_app_widget);
// 讀取指定編號的記事物件
ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
Item item = itemDAO.get(id);
// 設定小工具畫面顯示記事標題
views.setTextViewText(R.id.appwidget_text,
item != null ? item.getTitle() : "NA");
// 點選小工具畫面的記事標題後,啟動記事應用程式
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pending = PendingIntent.getActivity(
context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.appwidget_text, pending);
// 更新小工具
appWidgetManager.updateAppWidget(appWidgetId, views);
}
17-4 執行小工具與設定元件的設定
最後記得要在應用程式設定檔中,使用「receiver」標籤為小工具元件加入需要的設定。小工具設定元件也需要使用「activity」加入必要的設定。開啟「AndroidManifest.xml」檢視裡面設定的內容:
<!-- 小工具元件 -->
<receiver android:name=".ItemAppWidget" >
<!-- 一定要加入這個Action名稱的設定 -->
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<!-- 使用android:resource指定小工具專用設定檔的資源名稱 -->
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/item_app_widget_info" />
</receiver>
<!-- 小工具設定元件 -->
<activity android:name=".ItemAppWidgetConfigureActivity" >
<!-- 一定要加入這個設定 -->
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
完成這一章所有的功能了,執行應用程式,使用一開始介紹的方式,加入幾個記事小工具。
課程相關的檔案都可以GitHub瀏覽與下載。
http://github.com/macdidi5/Android-6-Tutorial
後續 >> Android 6 Tutorial 第六堂(1)Material Design – Theme 與 Transition
|