Android實戰技巧之六 PreferenceActivity使用詳解
一、寫作前面
當我們做應用的時候,需要使用者配置一些資訊,而這就是通常所說的應用設定。
對於Android系統來說,系統本身的設定帶來的使用者體驗和習慣已經深入人心,在我們的應用中同樣用到類似的設定頁,
那麼使用者使用起來就會更加親切和方便。是嗎?那我們應該怎麼做到呢?這就要靠本文的主人公PreferenceActivity了。
二、設定的細節
開啟Android手機的設定,如下圖:
我們會看到整個頁面被分為幾組:無線網路、裝置、個人、賬戶和系統。這個分組(或者叫分類)就是PreferenceCategory。
Wifi右邊有開關,這一項就是CheckBoxPreference;其他還有ListPreference和EditTextPreference。
你的每一次設定,都會被Preference存下來,這就是setting的資料持久化。
三、如何實現自己的設定
下面我們來實現一個設定程式,看看PreferenceActivity的基本知識都有哪些。
首先要說的是,PreferenceActivity從API level1中就加入了,那麼後續自Android3.0後有了Fragment的概念,同時也帶來了PreferenceFragment,這是後話,今天我們先講講簡單的。
這個例子有兩個Activity組成,第一個是MainAcitivity,程式啟動後直接到此,用來現實Setting中的各項設定內容;第二個是Setting,繼承自PreferenceActivity,展示如何設定和資料儲存操作等。我只是想演示PreferenceActivity相關的知識,UI是直接託的,layout中也用了Hardcode,請看官只是取其精華(如果有的話),去其糟粕。
1.Setting
先來說說重頭戲PreferenceActivity,它並不像普通的Activity那樣用layout來做自己的介面,它是用專屬的xml/preference.xml來構建自己的介面,然後在類中加入此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),First Category和Second Category.
每一個Preference中的都會包含一個key(android:key),它的功能相當於普通layout中的id。title:這一項的標題,字型比較大。
summary:摘要,標題下面的文字,字型較小。defaultValue:為設定summary之前的預設值。
其中陣列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類就可以執行起來了。其實就是這麼簡單。也許你會問,我們設定了自己的偏好值,程式中如何獲得呢?
我們需要註冊一個Preference變化的Listener來監聽這些事件。當我們做好設定後,Preference已經替我們做好了資料持久化了。我們可以用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的功能就實現了。那麼,在其他Activity中如何獲得設定的值呢?也是用sharedPreference來實現:
看看我的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; }}
當然,就像用edit text一樣,我們可以限制輸入的是文字還是數字或者是字母。就像上面程式碼:android:numeric="integer"