當(dāng)我們做應(yīng)用的時候,需要用戶配置一些信息,而這就是通常所說的應(yīng)用設(shè)置。
對于 Android 系統(tǒng)來說,系統(tǒng)本身的設(shè)置帶來的用戶體驗和習(xí)慣已經(jīng)深入人心,在我們的應(yīng)用中同樣用到類似的設(shè)置頁,那么用戶使用起來就會更加親切和方便。是嗎?那我們應(yīng)該怎么做到呢?這就要靠本文的主人公 PreferenceActivity 了。
打開 Android 手機的設(shè)置,如下圖:
http://wiki.jikexueyuan.com/project/android-actual-combat-skills/images/6-1.png" alt="fig.1" />
我們會看到整個頁面被分為幾組:無線網(wǎng)絡(luò)、設(shè)備、個人、賬戶和系統(tǒng)。這個分組(或者叫分類)就是 PreferenceCategory。
Wifi 右邊有開關(guān),這一項就是 CheckBoxPreference;其他還有 ListPreference 和 EditTextPreference。
你的每一次設(shè)置,都會被 Preference 存下來,這就是 setting 的數(shù)據(jù)持久化。
下面我們來實現(xiàn)一個設(shè)置程序,看看 PreferenceActivity 的基本知識都有哪些。
首先要說的是,PreferenceActivity 從 API level1 中就加入了,那么后續(xù)自 Android3.0后有了 Fragment 的概念,同時也帶來了 PreferenceFragment,這是后話,今天我們先講講簡單的。
這個例子有兩個 Activity 組成,第一個是 MainAcitivity,程序啟動后直接到此,用來現(xiàn)實Setting中的各項設(shè)置內(nèi)容;第二個是 Setting,繼承自PreferenceActivity,展示如何設(shè)置和數(shù)據(jù)存儲操作等。我只是想演示 PreferenceActivity 相關(guān)的知識,UI 是直接托的,layout 中也用了 Hardcode,請看官只是取其精華(如果有的話),去其糟粕。
1.Setting
先來說說重頭戲 PreferenceActivity,它并不像普通的 Activity 那樣用 layout 來做自己的界面,它是用專屬的 xml/preference.xml 來構(gòu)建自己的界面,然后在類中加入此xml。
本例演示三種常用 preference,如下代碼:
preferenc.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="First Category">
<ListPreference
android:key="list_key"
android:defaultValue="list key default value"
android:title="list title"
android:summary="list_summary"
android:entries="@array/list_preference"
android:entryValues="@array/list_preference"
android:dialogTitle="list_dialog_title" />
</PreferenceCategory>
<PreferenceCategory android:title="Second Category">
<EditTextPreference
android:key="edittext_key"
android:defaultValue="edit default value"
android:summary="edit summary"
android:title="edit title" />
<CheckBoxPreference
android:key="checkbox_key"
android:defaultValue="checkbox default value"
android:summary="checkbox summary"
android:title="checkbox title"
/>
<EditTextPreference
android:key="num_key"
android:defaultValue="0"
android:summary="edit summary"
android:numeric="integer"
android:title="input number" />
</PreferenceCategory></PreferenceScreen>
我將這三項 preference 分成兩組(PreferenceCategory),F(xiàn)irst Category 和 Second Category.
每一個 Preference 中的都會包含一個 key(android:key),它的功能相當(dāng)于普通 layout 中的 id。
title:這一項的標(biāo)題,字體比較大。
summary:摘要,標(biāo)題下面的文字,字體較小。
defaultValue:為設(shè)置 summary 之前的默認值。
其中數(shù)組 list_preference 在 array.xml 中定義:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="list_preference">
<item>Red</item>
<item>Blue</item>
<item>Green</item>
</string-array>
</resources>
Setting 中是怎樣加入這些 UI 信息呢?
public class Setting extends PreferenceActivity implements OnSharedPreferenceChangeListener {
private EditTextPreference mEtPreference;
private ListPreference mListPreference;
private CheckBoxPreference mCheckPreference;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
initPreferences();
}
private void initPreferences() {
mEtPreference = (EditTextPreference)findPreference(Consts.EDIT_KEY);
mListPreference = (ListPreference)findPreference(Consts.LIST_KEY);
mCheckPreference = (CheckBoxPreference)findPreference(Consts.CHECKOUT_KEY);
}
此時,這個 setting 類就可以運行起來了。其實就是這么簡單。也許你會問,我們設(shè)置了自己的偏好值,程序中如何獲得呢?
我們需要注冊一個 Preference 變化的 Listener 來監(jiān)聽這些事件。當(dāng)我們做好設(shè)置后,Preference 已經(jīng)替我們做好了數(shù)據(jù)持久化了。 我們可以用 sharedPreference 來獲得這些值。
下面來看:
@Override
protected void onResume() {
super.onResume();
// Setup the initial values
SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
mListPreference.setSummary(sharedPreferences.getString(Consts.LIST_KEY, ""));
mEtPreference.setSummary(sharedPreferences.getString(Consts.EDIT_KEY, "linc"));
// Set up a listener whenever a key changes
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onPause() {
super.onPause();
// Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(Consts.EDIT_KEY)) {
mEtPreference.setSummary(
sharedPreferences.getString(key, "20"));
} else if(key.equals(Consts.LIST_KEY)) {
mListPreference.setSummary(sharedPreferences.getString(key, ""));
}
}
到此,setting 的功能就實現(xiàn)了。那么,在其他 Activity 中如何獲得設(shè)置的值呢?也是用 sharedPreference 來實現(xiàn):
看看我的 MainActivity:
package com.linc.howtopreferenceactivity;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button btnSetting,btnShow;
private TextView tvCheckout,tvList,tvEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
btnSetting = (Button)findViewById(R.id.btn_setting);
btnShow = (Button)findViewById(R.id.btn_show);
btnSetting.setOnClickListener(buttonListener);
btnShow.setOnClickListener(buttonListener);
tvCheckout = (TextView)findViewById(R.id.tv_checkout);
tvList = (TextView)findViewById(R.id.tv_list);
tvEditText = (TextView)findViewById(R.id.tv_edittext);
}
private OnClickListener buttonListener = new OnClickListener() {
@Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.btn_setting:
startActivity(new Intent(MainActivity.this,Setting.class));
break;
case R.id.btn_show:
showSettingInfo();
break;
}
}
};
private void showSettingInfo() {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
tvCheckout.setText(settings.getBoolean(Consts.CHECKOUT_KEY, false)+"");
tvEditText.setText(settings.getString (Consts.EDIT_KEY, ""));
tvList.setText(settings.getString(Consts.LIST_KEY, "linc"));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
當(dāng)然,就像用 edit text 一樣,我們可以限制輸入的是文字還是數(shù)字或者是字母。就像上面代碼:android:numeric="integer"
完整代碼在此:HowToPreferenceActivity