第三堂(2)储存与读取应用程式资讯

应用程式在运作的时候,可能需要储存与读取一些简单的资料,另外可能也需
要提供一个画面让使用者设定一些应用程式需要的资讯。例如一个游戏应用程
式,需要在使用者完成一个关卡后,储存分数或花费的时间。还有提供游戏效
果的设定画面,让使用者设定是否需要背景音乐、音效和震动的效果。应用程
式可以读取这些设定的资料,用来控制游戏进行的时候,是否需要执行这些效
果。

Android 系统提供一种“Preference”的架构,它可以在应用程式中储存一些“名称=值”这类简单的资料,这些资料可以用来储存应用程式的状态,或是储存使用者执行的设定。这些资料在应用程式中执行储存与读取的工作都非常容易,如果有这类的需求,使用它来处理是最方便的。

这一章介绍Android提供的设计元件“PreferenceActivity”,使用它提供的设计方式,可以简化设定元件。完成这一章的工作以后,使用者可以在应用程式的主画面选择设定功能项目:

AndroidTutorial5_03_02_01

启动设定元件以后,使用者可以选择设定默认颜色或提醒时间:

AndroidTutorial5_03_02_02

使用者选择设定默认颜色的项目,应用程式启动之前已经设计好的选择颜色元件:

AndroidTutorial5_03_02_03

使用者选择设定默认提醒时间的项目,应用程式开启选择时间的对话框:

AndroidTutorial5_03_02_04

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

文章导航