應用程式在運作的時候,可能需要儲存與讀取一些簡單的資料,另外可能也需
要提供一個畫面讓使用者設定一些應用程式需要的資訊。例如一個游戲應用程
式,需要在使用者完成一個關卡后,儲存分數或花費的時間。還有提供游戲效
果的設定畫面,讓使用者設定是否需要背景音樂、音效和震動的效果。應用程
式可以讀取這些設定的資料,用來控制游戲進行的時候,是否需要執行這些效
果。
Android 系統提供一種“Preference”的架構,它可以在應用程式中儲存一些“名稱=值”這類簡單的資料,這些資料可以用來儲存應用程式的狀態,或是儲存使用者執行的設定。這些資料在應用程式中執行儲存與讀取的工作都非常容易,如果有這類的需求,使用它來處理是最方便的。
這一章介紹Android提供的設計元件“PreferenceActivity”,使用它提供的設計方式,可以簡化設定元件。完成這一章的工作以后,使用者可以在應用程式的主畫面選擇設定功能項目:
[](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_01.png)
啟動設定元件以后,使用者可以選擇設定默認顏色或提醒時間:
[](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_02.png)
使用者選擇設定默認顏色的項目,應用程式啟動之前已經設計好的選擇顏色元件:
[](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_03.png)
使用者選擇設定默認提醒時間的項目,應用程式開啟選擇時間的對話框:
[](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_04.png)
## 10-1 系統Preference設計架構介紹
一般的應用程式,通常需要提供使用者執行設定的功能,這樣可以讓應用程式
比較方便一些,不會是固定的畫面或操作的行為。Android 為應用程式提供一個專門用來設計應用程式設定功能的元件,它是一個比較特別的Activity 元件,規劃與設計的作法也很不一樣。要使用這種比較方便而且容易的設定元件,需要設計這些設定檔與元件:
* 設定畫面配置檔 – 這種設定元件有它特有的畫面配置檔,也是一個XML 格
式的檔案,放在專案的“res/xml”目錄下,使用特別的標簽設計畫面。
* PreferenceActivity元件 – 設定元件專用的Activity元件,讓你的元件類別繼承自這個類別。
設定元件專用的畫面配置檔放在專案的“res/xml”目錄下,這個設定檔的最外層使用“PreferenceScreen”標簽,根據應用程式需要的設定資料,在這里標簽中加入這些需要的設定元件標簽:
* EditTextPreference – 使用對話框讓使用者輸入文字資料。
* CheckBoxPreference – 勾選元件,儲存boolean 資料。
* SwitchPreference – 在Android 4.0(API level 14)加入,提供開關式的元
件,儲存boolean 資料。
* ListPreference – 使用對話框讓使用者在列表中選擇一個項目,儲存字串資料。
* MultiSelectListPreference – 在Android 3.0(API level 11)加入,使用對話框讓使用者在列表中選擇多個項目,儲存Set 資料。
* RingtonePreference – 開啟系統內建選擇來電鈴聲的對話框讓使用者選擇,儲存文字資料。
* PreferenceCategory – 用來執行設定資料的分組。
* Preference – 啟動其它元件執行設定的工作。
## 10-2 設計設定元件使用的畫面配置檔
你的應用程式可以依照需要保存的資訊,設計好設定畫面讓使用者使用,設定畫面使用一組特定的元件標簽。這個記事應用程式除了說明一個一般的元件外,也會說明啟動元件的作法,其它的設定元件就會比較簡單一些,你可以依照自己的需求加入與測試其它設定元件。
設定元件需要使用一些文字資源,開啟“res/values/strings.xml”,加入下列的文字資源:
~~~
<string name="default_color">默認的顏色</string>
<string name="default_color_summary">新增記事的默認顏色</string>
<string name="default_notify">默認提醒時間</string>
<string name="default_notify_summary">在指定的時間之前通知</string>
<string-array name="notify_minutes_array">
<item>五分鐘</item>
<item>十分鐘</item>
<item>二十分鐘</item>
<item>三十分鐘</item>
<item>六十分鐘</item>
</string-array>
<string-array name="notify_minutes_value_array">
<item>5</item>
<item>10</item>
<item>20</item>
<item>30</item>
<item>60</item>
</string-array>
~~~
設定畫面配置檔必須放在專案的“res/xml”目錄下,如果專案中還沒有這個目錄,在“res”目錄按鼠標右鍵,選擇“New -> Directory”,輸入“xml”以后選擇“OK”。在“res/xml”目錄按鼠標右鍵,選擇“New -> XML resource file”,在File name輸入“mypreference”以后選擇“OK”。把“mypreference.xml”修改為下列的內容:
~~~
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 默認顏色 -->
<!-- android:key 設定資料名稱 -->
<!-- android:title 設定畫面上顯示的標題 -->
<!-- android:summary 設定畫面上顯示的說明 -->
<Preference
android:key="DEFAULT_COLOR"
android:title="@string/default_color"
android:summary="@string/default_color_summary">
</Preference>
<!-- 默認提醒時間 -->
<!-- android:entries 設定畫面顯示選項內容的陣列資源 -->
<!-- android:entriyValues 設定儲存選項資料的陣列資源 -->
<!-- android:defaultValue 設定選項默認項目編號 -->
<ListPreference
android:key="NOTIFY_MINUTES"
android:title="@string/default_notify"
android:summary="@string/default_notify_summary"
android:entries="@array/notify_minutes_array"
android:entryValues="@array/notify_minutes_value_array"
android:defaultValue="5" />
</PreferenceScreen>
~~~
這個檔案在設定畫面中提供兩個設定用的項目,一個用來設定新增記事的默認顏色,還有設定提醒的默認時間,這一章會先使用默認顏色的設定值,提醒的默認時間在后面才會用到。
## 10-2 設計設定元件
設定元件是一個比較特殊的Activity元件,它是繼承自“PreferenceActivity”的子類別,最基本的作法只要在覆寫的onCreate 方法中,呼叫“addPreferencesFromResource”方法指定元件使用的設定畫面資源就可以了。在“net.macdidi.myandroidtutorial”目錄按鼠標右鍵,選擇“New -> Java Class”,在Name輸入“PrefActivity”以后選擇“OK”。把PrefActivity.java改為下列的內容:
~~~
package net.macdidi.myandroidtutorial;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class PrefActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 指定使用的設定畫面配置資源
// 這行敘述從API Level 11開始會產生警告訊息
// 不過不會影響應用程式的運作
addPreferencesFromResource(R.xml.mypreference);
}
}
~~~
跟其它的Activity元件一樣,設定元件同樣需要在“AndroidManifest.xml”檔案中加入必要的設定:
~~~
<!-- 設定元件 -->
<activity
android:name="net.macdidi.myandroidtutorial.PrefActivity" />
~~~
完成設定元件的設計以后,開啟“res/menu/main_menu.xml”檔案,為功能表加入啟動設定元件的項目:
~~~
<!-- 設定 -->
<item
android:title="Setting"
app:showAsAction="always"
android:icon="@android:drawable/ic_menu_preferences"
android:onClick="clickPreferences" />
~~~
開啟“net.macdidi.myandroidtutorial”套件下的“MainActivity”類別,加入啟動設定元件的方法宣告:
~~~
// 設定
public void clickPreferences(MenuItem item) {
// 啟動設定元件
startActivity(new Intent(this, PrefActivity.class));
}
~~~
完成這個階段的工作以后,可以先執行應用程式,選擇主功能表上的設定圖示,看看可不可以正確的啟動設定元件。
## 10-3 在設計設定元件中啟動其它元件
選擇記事分類顏色的元件在之前已經設計好了,所以需要讓使用者選擇默認顏色最好的作法,應該是使用原來設計好的元件,再稍微修改就可以了。選擇記事分類顏色元件在這里需讓設定元件使用,所以在“AndroidManifest.xml”檔案修改它的設定:
~~~
<!-- 選擇顏色 -->
<activity
android:name="net.macdidi.myandroidtutorial.ColorActivity"
android:theme="@android:style/Theme.Dialog"
android:label="@string/title_activity_color">
<!-- 加入設定元件啟動用的Action名稱 -->
<intent-filter>
<action android:name="net.macdidi.myandroidtutorial.CHOOSE_COLOR"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
~~~
開啟“res/xml/mypreference.xml,加入啟動選擇顏色元件的設定:
~~~
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<Preference
android:key="DEFAULT_COLOR"
android:title="@string/default_color"
android:summary="@string/default_color_summary">
<!-- 啟動選擇顏色元件 -->
<intent
android:action="net.macdidi.myandroidtutorial.CHOOSE_COLOR"
android:targetPackage="net.macdidi.myandroidtutorial"
android:targetClass="net.macdidi.myandroidtutorial.ColorActivity"/>
</Preference>
...
</PreferenceScreen>
~~~
開啟在“net.macdidi.myandroidtutorial”套件下的“ColorActivity”類別,找到“ColorListener”監聽類別,依照下列的說明修改原來的程式碼:
~~~
private class ColorListener implements OnClickListener {
@Override
public void onClick(View view) {
String action = ColorActivity.this.getIntent().getAction();
// 經由設定元件啟動
if (action != null &&
action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
// 建立SharedPreferences物件
SharedPreferences.Editor editor =
PreferenceManager.getDefaultSharedPreferences(
ColorActivity.this).edit();
// 儲存默認顏色
editor.putInt("DEFAULT_COLOR", view.getId());
// 寫入設定值
editor.commit();
finish();
}
// 經由新增或修改記事的元件啟動
else {
Intent result = getIntent();
result.putExtra("colorId", view.getId());
setResult(Activity.RESULT_OK, result);
finish();
}
}
}
~~~
為了接下來設計讀取顏色設定的功能,開啟在“net.macdidi.myandroidtutorial”套件下的“ItemActivity”類別,找到“getColors”方法,參考下列的說明修改這個方法的宣告:
~~~
// 改為public static
public static Colors getColors(int color) {
...
}
~~~
使用者設定默認的顏色以后,通常會希望在設定元件的畫面看到設定的結果,所以回到“PrefActivity”類別,依照下列的說明加入需要的程式碼:
~~~
package net.macdidi.myandroidtutorial;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
public class PrefActivity extends PreferenceActivity {
// 加入字段變量宣告
private SharedPreferences sharedPreferences;
private Preference defaultColor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.mypreference);
// 讀取顏色設定元件
defaultColor = (Preference)findPreference("DEFAULT_COLOR");
// 建立SharedPreferences物件
sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(this);
}
@Override
protected void onResume() {
super.onResume();
// 讀取設定的默認顏色
int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
if (color != -1) {
// 設定顏色說明
defaultColor.setSummary(getString(R.string.default_color_summary) +
": " + ItemActivity.getColors(color));
}
}
}
~~~
完成這個階段的工作以后,執行應用程式,選擇設定默認顏色的項目,看看可不可以正確的啟動選擇顏色元件。選擇顏色并回到設定元件以后,默認顏色設定項目的說明也會顯示設定顏色的名稱。
## 10-4 使用儲存的設定值
完成設定元件與相關的設計后,使用者在新增的記事資料的時候,如果沒有為它設定顏色,就應該采用已經在設定元件設定好的默認顏色。開啟在“net.macdidi.myandroidtutorial”套件下的“ItemActivity”類別,找到“onSubmit”方法,依照下列的說明執行需要的修改:
~~~
public void onSubmit(View view) {
if (view.getId() == R.id.ok_teim) {
String titleText = title_text.getText().toString();
String contentText = content_text.getText().toString();
item.setTitle(titleText);
item.setContent(contentText);
if (getIntent().getAction().equals(
"net.macdidi.myandroidtutorial.EDIT_ITEM")) {
item.setLastModify(new Date().getTime());
}
// 新增記事
else {
item.setDatetime(new Date().getTime());
// 建立SharedPreferences物件
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(this);
// 讀取設定的默認顏色
int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
item.setColor(getColors(color));
}
Intent result = getIntent();
result.putExtra("net.macdidi.myandroidtutorial.Item", item);
setResult(Activity.RESULT_OK, result);
}
// 結束
finish();
}
~~~
完成這一章所有的工作了,執行應用程式,新增一個記事資料,看看會不會設定為默認的顏色。
[](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_05.png)
- 第一堂
- 第一堂(1)西游記里的那只猴子
- 第一堂(2)準備 Android Studio 開發環境
- 第一堂(3)開始設計 Android 應用程式
- 第一堂(4)開發 Android 應用程式的準備工作
- 第二堂
- 第二堂(1)規劃與建立應用程式需要的資源
- 第二堂(2)設計應用程式使用者界面
- 第二堂(3)應用程式與使用者的互動
- 第二堂(4)建立與使用 Activity 元件
- 第三堂
- 第三堂(1)為ListView元件建立自定畫面
- 第三堂(2)儲存與讀取應用程式資訊
- 第三堂(3)Android 內建的 SQLite 數據庫
- 第四堂
- 第四堂(1)使用照相機與麥克風
- 第四堂(2)設計地圖應用程式 - Google Maps Android API v2
- 第四堂(3)讀取裝置目前的位置 - Google Services Location
- 第五堂
- 第五堂(1)建立廣播接收元件 - BroadcastReceiver
- 第五堂(2)系統通知服務 - Notification
- 第五堂(3)設計小工具元件 - AppWidget
- 第六堂
- 第六堂(1)Material Design - Theme與Transition
- 第六堂(2)Material Design - RecylerView
- 第六堂(3)Material Design - Shared Element與自定動畫效果