应用程式在运作的时候,可能需要储存与读取一些简单的资料,另外可能也需
要提供一个画面让使用者设定一些应用程式需要的资讯。例如一个游戏应用程
式,需要在使用者完成一个关卡后,储存分数或花费的时间。还有提供游戏效
果的设定画面,让使用者设定是否需要背景音乐、音效和震动的效果。应用程
式可以读取这些设定的资料,用来控制游戏进行的时候,是否需要执行这些效
果。
Android 系统提供一种“Preference”的架构,它可以在应用程式中储存一些“名称=值”这类简单的资料,这些资料可以用来储存应用程式的状态,或是储存使用者执行的设定。这些资料在应用程式中执行储存与读取的工作都非常容易,如果有这类的需求,使用它来处理是最方便的。
这一章介绍Android提供的设计元件“PreferenceActivity”,使用它提供的设计方式,可以简化设定元件。完成这一章的工作以后,使用者可以在应用程式的主画面选择设定功能项目:
[![AndroidTutorial5_03_02_01](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_01-189x300.png)](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_01.png)
启动设定元件以后,使用者可以选择设定默认颜色或提醒时间:
[![AndroidTutorial5_03_02_02](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_02-190x300.png)](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_02.png)
使用者选择设定默认颜色的项目,应用程式启动之前已经设计好的选择颜色元件:
[![AndroidTutorial5_03_02_03](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_03-190x300.png)](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_03.png)
使用者选择设定默认提醒时间的项目,应用程式开启选择时间的对话框:
[![AndroidTutorial5_03_02_04](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_04-189x300.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();
}
~~~
完成这一章所有的工作了,执行应用程式,新增一个记事资料,看看会不会设定为默认的颜色。
[![AndroidTutorial5_03_02_05](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_02_05-190x300.png)](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与自定动画效果