Android Tutorial 第五堂(3)設計小工具元件 - AppWidget by Michael | CodeData
top

Android Tutorial 第五堂(3)設計小工具元件 - AppWidget

分享:

專欄作者新書出版:Android App程式開發剖析 第三版(適用Android 8 Oreo與Android Studio 3)

Android Tutorial 第五堂(2)系統通知服務 – Notification << 前情

一般個人電腦或行動裝置的作業系統,可以在桌面上放置應用程式的捷徑,使用明顯的圖示和應用程式的名稱,讓使用者在桌面上直接啟動常用的應用程式。一些使用者經常操作的功能,例如開啟或關閉裝置的網路或藍牙設備,如果可以不用啟動這些設定的應用程式,使用者就可以在桌面上直接操作這些功能,那應該會比較方便一些。

Android平台提供一種特別的元件「AppWidget」,它可以讓使用者在桌面上直接瀏覽資料,或是執行一些簡單的操作。例如在桌面上顯示時間、行事曆或氣候資訊,這種元件通常會把它稱為「小工具」元件。

這一章介紹設計AppWidget元件的作法,它的設計方式跟其它元件很不一樣。完成這一章的工作以後,為記事應用程式加入新的小工具元件。使用者在畫面長按以後,Android會開啟這樣的畫面,選擇「小工具」:

AndroidTutorial5_05_03_01

在選擇小工具的畫面,找到為記事應用應用程式設計好的元件,長按以後把它放到畫面指定的位置:

AndroidTutorial5_05_03_02

決定小工具的位置以後,元件自動開啟選擇記事的畫面,選擇其中一個記事項目:

AndroidTutorial5_05_03_03

畫面上就會放置一個顯示記事標題的小工具元件:

AndroidTutorial5_05_03_04

依照同樣的步驟,可以在畫面加入其它顯示記事標題的小工具:

AndroidTutorial5_05_03_05

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」按鈕:

AndroidTutorial5_05_03_06

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 :自動加入小工具元件與小工具設定元件的設定。

實作小工具設定元件

使用者選擇記事小工具以後,必須先啟動選擇記事項目元件。小工具元件在專用的設定檔可以設定這個功能,開啟「res/xml/itemappwidget_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:minWidth="250dp"
    android:minHeight="40dp"
    android:updatePeriodMillis="86400000"
    android:previewImage="@drawable/example_appwidget_preview"
    android:initialLayout="@layout/item_app_widget"
    android:configure="net.macdidi.myandroidtutorial.ItemAppWidgetConfigureActivity"
    android:widgetCategory="home_screen"
    android:initialKeyguardLayout="@layout/item_app_widget"></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;
    }
}

完成需要的程式碼以後,類別中有許多預設的內容已經不會用到,建議刪除它們。

實作小工具元件

接下來修改預設的小工具元件類別與畫面資源。開啟「res/layout/itemappwidget.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);
}

小工具與設定元件設定

最後記得要在應用程式設定檔中,使用「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瀏覽與下載。

https://github.com/macdidi5/AndroidTutorial

後續 >> Android Tutorial 第六堂(1)Material Design – Theme 與 Transition

分享:
按讚!加入 CodeData Facebook 粉絲群

相關文章

留言

留言請先。還沒帳號註冊也可以使用FacebookGoogle+登錄留言

熱門論壇文章

熱門技術文章