本文主要介绍SharedPreferences和PreferenceActivity的用法。

主要资料来源于网络,包括但不限于:

《Android之PreferenceActivity》

《在Android中Preferences数据存储的使用》

《Android的设置界面及Preference使用》

《OnPreferenceChangeListener分析,以及与OnPreferenceClickListener的区别》

《使用PreferenceActivity时,如何获取ListPreference中选中的值》。

1、android文件存储

对Android系统了解的都知道,Android系统有四种基本的数据保存方法,一是SharedPreference,二是文件,三是SQLite,四是ContentProvider。看出来了吧,Preference,对就是使用SharedPreferneces以键值对的形式进行保存的。

2、SharedPreferneces

做软件开发应该都知道,很多软件会有配置文件,里面存放这程序运行当中的各个属性值,由于其配置信息并不多,如果采用数据库来存放并不划算,因为数据库连接跟操作等耗时大大影响了程序的效率,因此我们使用键值这种一一对应的关系来存放这些配置信息。SharedPreferences正是Android中用于实现这中存储方式的技术。
SharedPreferences是以键值对的形式存储数据的,其使用非常简单,能够轻松的存放数据和读取数据。

在具体介绍Android的设置界面的实现之前,我们先来介绍一下预备知识,就是Android数据持久化方法中最简单的一种,即使用Preferences的键值对存储方式。这种方式主要用来存储比较简单的一些数据,而且是标准的Boolean、Int、Float、Long、String等类型。

android.content.SharedPreferences是一个接口,用来获取和修改持久化存储的数据。有三种获取系统中保存的持久化数据的方式:

1). public SharedPreferences getPreferences (int mode)
通过Activity对象获取,获取的是本Activity私有的Preference,保存在系统中的xml形式的文件的名称为这个Activity的名字,因此一个Activity只能有一个,属于这个Activity。
2). public SharedPreferences getSharedPreferences (String name, int mode)
因为Activity继承了ContextWrapper,因此也是通过Activity对象获取,但是属于整个应用程序,可以有多个,以第一参数的name为文件名保存在系统中。
3). public static SharedPreferences getDefaultSharedPreferences (Context context)
PreferenceManager的静态函数,保存PreferenceActivity中的设置,属于整个应用程序,但是只有一个,Android会根据包名和PreferenceActivity的布局文件来起一个名字保存。
通过以上方式取得SharedPreferences后就可以对数据进行读取或者保存了。
保存方式如下:

[java] view plaincopy
  1. StringSTORE_NAME="Settings";
  2. SharedPreferencessettings=getSharedPreferences(STORE_NAME,MODE_PRIVATE);
  3. SharedPreferences.Editoreditor=settings.edit();
  4. editor.putInt("sourceType",0);
  5. editor.commit();

获得SharedPreferences,如果需要进行保存等修改操作,首先得通过其edit()方法获得SharedPreferences.Editor,然后就可以通过putInt、putString等方法以键值对(key-value)的方式保存数据,或者remove移除某个键(key),及调用clear方法删除所有内容。最后需要调用commit方法是使修改生效。读取方式如下:

[java] view plaincopy
  1. SharedPreferencessettings=getSharedPreferences(STORE_NAME,MODE_PRIVATE);
  2. intsource=settings.getInt("sorceType",1);

读取就更加简单了,只要获得SharedPreferences后,就可以通过getInt、getString等方法获取对应键(key)保存着的数据,如果没有找到key,则返回第二个参数作为默认值。

2、PreferencesActivity

在Android开发过程中我们有很大的机会需要用到参数设置功能,那么在Android应用中,我们如何实现参数设置界面及参数存储呢,下面我们来介绍一下Android中的一个特殊Activity–PreferencesActivity。
PreferencesActivity是Android中专门用来实现程序设置界面及参数存储的一个Activity。

2.1 创建PreferencesActivity

如何创建一个PreferenceActivity。 其实Eclipse提供了相应的创建工具,和创建Layout是基本相同的。步骤如下:
创建Android项目,并添加一个Android xml文件。注意,这次选择的不是Layout,而是Preference,而且注意Folder路径是 res/xml.


添加完成之后,在res/xml/下打开添加的preference.xml文件。可以看到Android也为我们提供两种编辑模式,可视化的结构设计及xml源码设计。推荐使用structure进行创建。如图所示:


2.2PrefeneceActivity的基本组成

下面我们看看PrefeneceActivity都提供了哪几种元素可供使用。点击Add按钮,在打开的新窗口中可以看到以下几项:


CheckBoxPreference:CheckBox选择项,对应的值的ture或flase。如图:


EditTextPreference:输入编辑框,值为String类型,会弹出对话框供输入。


ListPreference: 列表选择,弹出对话框供选择。


Preference:只进行文本显示,需要与其他进行组合使用。


PreferenceCategory:用于分组。效果如下:


PreferenceScreen:PreferenceActivity的根元素,必须为它。
RingtonePreference:系统玲声选择。


OK,Preferenc的基本元素介绍完毕,下一节将使用它们创建一个完整的Preference并进行显示。

2.3PreferenceActivity实例

分析MusicPlayer Setting,第一部分为“我的位置”,包括“使用无线网线”和“使用GPS”两个部分,而且都是CheckBox,根据上节学习,应该包括一个PreferenceCategory和两个CheckBoxPreference。
Xml代码

[html] view plaincopy
  1. <PreferenceCategoryandroid:title="我的位置"android:key="set_local">
  2. <CheckBoxPreferenceandroid:key="apply_wifi"
  3. android:summary="使用无线网络在应用程序(例如Google地图)中查看位置"
  4. android:title="使用无线网络"android:defaultValue="true">
  5. </CheckBoxPreference>
  6. <CheckBoxPreferenceandroid:key="apply_gps"
  7. android:summary="定位到街道级别(需要消耗更多的电量以及天气允许)"
  8. android:title="使用GPS">
  9. </CheckBoxPreference>
  10. </PreferenceCategory>

以上代码当然也可以用Android提供的IDE工具直接生成。视频结构如下:

PreferenceCategory属性分析:
title:显示的标题
key:唯一标识(至少在同一程序中是唯一),SharedPreferences也将通过此Key值进行数据保存,也可以通过key值获取保存的信息 (以下相同)。
CheckBoxPreference属性分析:
Key:唯一标识.
title:显示标题(大字体显示)
summary:副标题(小字体显示)
defaultValue:默认值(当然,此处只能是true或false了)
Preference.xml的第二部分为“无线和网络设置”,此部分包括的内容比较多,也稍微复杂,一步一步来分析。
xml代码:

[html] view plaincopy
  1. <PreferenceCategoryandroid:title="无线和网络设置">
  2. <CheckBoxPreferenceandroid:key="apply_fly"
  3. android:summary="禁用所有无线连接"android:title="飞行模式">
  4. </CheckBoxPreference>
  5. <CheckBoxPreferenceandroid:key="apply_internet"
  6. android:summary="禁用通过USB共享Internet连接"
  7. android:title="Internet共享">
  8. </CheckBoxPreference>
  9. <CheckBoxPreferenceandroid:key="apply_wifi"
  10. android:summary="打开Wi-Fi"android:title="Wi-Fi">
  11. </CheckBoxPreference>
  12. <Preferenceandroid:summary="设置和管理无线接入点"android:title="Wi-Fi设置"
  13. android:dependency="apply_wifi"android:key="wifi_setting">
  14. </Preference>
  15. <CheckBoxPreferenceandroid:key="apply_bluetooth"
  16. android:summary="启用蓝牙"android:title="蓝牙">
  17. </CheckBoxPreference>
  18. <Preferenceandroid:summary="管理连接、设备设备名称和可检测性"
  19. android:title="蓝牙设置"android:dependency="apply_bluetooth"
  20. android:key="bluetooth_setting">
  21. </Preference>
  22. <EditTextPreferenceandroid:key="number_edit"
  23. android:title="输入电话号码">
  24. </EditTextPreference>
  25. <ListPreferenceandroid:title="部门设置"android:entries="@array/department"
  26. android:entryValues="@array/department_value"
  27. android:dialogTitle="选择部门"
  28. android:key="depart_value">
  29. </ListPreference>
  30. <RingtonePreferenceandroid:ringtoneType="all"android:title="玲聲"
  31. android:showDefault="true"android:key="ring_key"
  32. android:showSilent="true">
  33. </RingtonePreference>
  34. </PreferenceCategory>

对应的Structure图:

第二部分中前三个都为CheckBoxPreference,不心多说,从<Preference android:key="bluetooth_setting"/>开始。
Preference属性分析:
Key:唯一标识.
title:显示标题(大字体显示)
summary:副标题(小字体显示)
dependency:附属(嘛意思),即标识此元素附属于某一个元素(通常为CheckBoxPreference),dependency值为所附属元素的key。上面代码中的Preference元素附属于key等于“apply_bluetooth”的CheckPreference元素,当CheckPreference值为true时,Preference则为可用,否则为不可用。
EditTextPreperence属性分析:
Key:唯一标识.
title:显示标题(大字体显示)
ListPreference属性分析:
Key:唯一标识.
title:显示标题(大字体显示)
dialogTitle:弹出对话框的标题
entries:列表中显示的值。为一个数组,通读通过资源文件进行设置。
entryValues:列表中实际保存的值,也entries对应。为一个数组,通读通过资源文件进行设置。以下代码显示的是arrays.xml文件中内容:

[html] view plaincopy
  1. <resources>
  2. <string-arrayname="department">
  3. <item>综合部</item>
  4. <item>行政部</item>
  5. <item>外贸部</item>
  6. </string-array>
  7. <string-arrayname="department_value">
  8. <item>001</item>
  9. <item>002</item>
  10. <item>003</item>
  11. </string-array>
  12. </resources>

点击“Add”按钮,就会添加新的标签,我们依次添加一个CheckBoxPreference和ListPreference。属于CheckBoxPreference的特有属性主要为Summary On和Summary Off,比较好理解。下面具体来看下ListPreference属性的填写:


我们可以看到,ListPreference除了继承自Preference的属性外,还有自己ListPreference的属性和继承自DialogPreference的属性。其中属于ListPreference的属性有两个:Entries填的为一个字符串数组,是列表显示出来的值,而Entry Values是长度对应的字符串数组,是和Entries对应的具体的值。DialogPreference只要填一个Dialog title标题和一个取消按钮显示的字即可。在Preference属性的Dependency中我们填写上面一个CheckBoxPreference的Key,这样就会只有在CheckBoxPreference勾选时这个ListPreference才有效。


最后把java文件中的addPreferencesFromResource(R.xml.preferences);改为addPreferencesFromResource(R.xml.preferencesii);
保存运行,看下效果。

RingtonePreference :玲声(暂时没有用到过),暂时略过。
OK,Preference.xml内容已经分析完毕,属性都大致相同,相信亲自动力一试也就那么回事。那么如何把Preference.xml中内容展现出来呢?
Layout是通过继续自Activity的类来进行显示的,前面提到过,PreferenceActivity是专门用于显示preference的,所以只要创建一个继承自PreferenceActivity类即可。代码如下:
[java] view plaincopy
  1. publicclassSettingextendsPreferenceActivity{
  2. @Override
  3. publicvoidonCreate(BundlesavedInstanceState){
  4. super.onCreate(savedInstanceState);
  5. //所的的值将会自动保存到SharePreferences
  6. addPreferencesFromResource(R.xml.preference);
  7. }
  8. }
接下来就是运行程序,显示劳动成果。至此,工作已经完成大半,所有的值都会保存到SharedPreferences中,我们也可以读取到保存的结果。

2.4如何获取ListPreference中选中的值

研究了一天,貌似ListPreference中根本就没有什么回调函数可以用
于是,向上一层,把注意力集中于SharedPreferences,
发现有这么个接口:onSharedPreferenceChanged
抱着试试看的态度,实现了该接口,发现此方法可行,先将部分代码分享如下:

[java] view plaincopy
  1. packageyinger.firewall;
  2. importandroid.content.SharedPreferences;
  3. importandroid.content.SharedPreferences.OnSharedPreferenceChangeListener;
  4. importandroid.os.Bundle;
  5. importandroid.preference.CheckBoxPreference;
  6. importandroid.preference.ListPreference;
  7. importandroid.preference.Preference;
  8. importandroid.preference.PreferenceActivity;
  9. importandroid.preference.PreferenceManager;
  10. importandroid.preference.PreferenceScreen;
  11. publicclassCallFireWallextendsPreferenceActivityimplements
  12. OnSharedPreferenceChangeListener{
  13. ListPreferencelp=null;
  14. StringwhiteMode="1";
  15. StringblackMode="2";
  16. /**Calledwhentheactivityisfirstcreated.*/
  17. @Override
  18. publicvoidonCreate(BundlesavedInstanceState){
  19. super.onCreate(savedInstanceState);
  20. addPreferencesFromResource(R.xml.preferences);
  21. this.setTitle("Ying_er"+"CallSafe");
  22. SharedPreferencesprefs=PreferenceManager
  23. .getDefaultSharedPreferences(this);
  24. prefs.registerOnSharedPreferenceChangeListener(this);
  25. lp=(ListPreference)findPreference(getString(R.string.pref_mode_key));
  26. }
  27. @Override
  28. publicbooleanonPreferenceTreeClick(PreferenceScreenpreferenceScreen,
  29. Preferencepreference){
  30. //TODOAuto-generatedmethodstub
  31. returnsuper.onPreferenceTreeClick(preferenceScreen,preference);
  32. }
  33. @Override
  34. publicvoidonSharedPreferenceChanged(SharedPreferencessharedPreferences,
  35. Stringkey){
  36. //TODOAuto-generatedmethodstub
  37. System.out.println("onSharedPreferenceChanged");
  38. if(key==getString(R.string.pref_mode_key)){
  39. System.out.println(lp.getValue());
  40. if(lp.getValue().equals(whiteMode)){
  41. }
  42. }
  43. }
  44. }

注意:该事件需要注册。既:

[java] view plaincopy
  1. prefs.registerOnSharedPreferenceChangeListener(this);

实际上,使用如下方法也是可以得到值的:

[java] view plaincopy
  1. PreferenceManager.getDefaultSharedPreferences(context).getBoolean(R.string.pref_mode_key,DEFAULT);

2.5OnPreferenceChangeListener

以上我们分别介绍了Preference对数据的保存及PreferenceActivity设置界面。当PreferenceActivity中的内容改变时,Android系统会自动进行保存和持久化维护,我们只需要在要用的设置界面中数据的地方进行读取就可以了。同时Android还提供了OnPreferenceClickListener和OnPreferenceChangeListener两个与Preference相关的监听接口,当PreferenceActivity中的某一个Preference进行了点击或者改变的操作时,都会回调接口中的函数,这样可以第一个时间向其他Activity等通知系统设置进行了改变。
下面我们以一个具体的Demo说明PreferenceActivity和其监听接口的使用。
新建一个工程AndroidPreferenceDemoII,并按上面的步骤添加xml文件夹和其内容Preferenceii.xml,还有values文件夹中的array.xml和strings.xml。
新建一个名为Settings的class,内容为:

[java] view plaincopy
  1. //继承PreferenceActivity,并实现OnPreferenceChangeListener和OnPreferenceClickListener监听接口
  2. publicclassSettingsextendsPreferenceActivityimplementsOnPreferenceChangeListener,
  3. OnPreferenceClickListener{
  4. //定义相关变量
  5. StringupdateSwitchKey;
  6. StringupdateFrequencyKey;
  7. CheckBoxPreferenceupdateSwitchCheckPref;
  8. ListPreferenceupdateFrequencyListPref;
  9. @Override
  10. publicvoidonCreate(BundlesavedInstanceState){
  11. super.onCreate(savedInstanceState);
  12. //从xml文件中添加Preference项
  13. addPreferencesFromResource(R.xml.preferencesii);
  14. //获取各个Preference
  15. updateSwitchKey=getResources().getString(R.string.auto_update_switch_key);
  16. updateFrequencyKey=getResources().getString(R.string.auto_update_frequency_key);
  17. updateSwitchCheckPref=(CheckBoxPreference)findPreference(updateSwitchKey);
  18. updateFrequencyListPref=(ListPreference)findPreference(updateFrequencyKey);
  19. //为各个Preference注册监听接口
  20. updateSwitchCheckPref.setOnPreferenceChangeListener(this);
  21. updateSwitchCheckPref.setOnPreferenceClickListener(this);
  22. updateFrequencyListPref.setOnPreferenceChangeListener(this);
  23. updateFrequencyListPref.setOnPreferenceClickListener(this);
  24. }
  25. @Override
  26. publicbooleanonPreferenceChange(Preferencepreference,ObjectnewValue){
  27. //TODOAuto-generatedmethodstub
  28. Log.v("SystemSetting","preferenceischanged");
  29. Log.v("Key_SystemSetting",preference.getKey());
  30. //判断是哪个Preference改变了
  31. if(preference.getKey().equals(updateSwitchKey))
  32. {
  33. Log.v("SystemSetting","checkboxpreferenceischanged");
  34. }
  35. elseif(preference.getKey().equals(updateFrequencyKey))
  36. {
  37. Log.v("SystemSetting","listpreferenceischanged");
  38. }
  39. else
  40. {
  41. //如果返回false表示不允许被改变
  42. returnfalse;
  43. }
  44. //返回true表示允许改变
  45. returntrue;
  46. }
  47. @Override
  48. publicbooleanonPreferenceClick(Preferencepreference){
  49. //TODOAuto-generatedmethodstub
  50. Log.v("SystemSetting","preferenceisclicked");
  51. Log.v("Key_SystemSetting",preference.getKey());
  52. //判断是哪个Preference被点击了
  53. if(preference.getKey().equals(updateSwitchKey))
  54. {
  55. Log.v("SystemSetting","checkboxpreferenceisclicked");
  56. }
  57. elseif(preference.getKey().equals(updateFrequencyKey))
  58. {
  59. Log.v("SystemSetting","listpreferenceisclicked");
  60. }
  61. else
  62. {
  63. returnfalse;
  64. }
  65. returntrue;
  66. }
[java] view plaincop

当然重写PreferenceActivity的 onPreferenceTreeClick的方法就可以了,通过参数preference来判断是对那一个元素进行的,并根据需要进行操作。

[java] view plaincopy
  1. @Override
  2. publicbooleanonPreferenceTreeClick(PreferenceScreenpreferenceScreen,
  3. Preferencepreference){
  4. returnfalse;
  5. }

2.5 OnPreferenceChangeListener与OnPreferenceClickListener的区别

两种监听器OnPreferenceChangeListener和OnPreferenceClickListener,OnPreferenceClickListener的意思好理解,但是OnPreferenceChangeListener就不好懂了,所以就写了个Demo分析了一下,代码如下:

[java] view plaincopy
  1. <p></p><prename="code"class="java">packagecom.luther.test;
  2. importcom.luther.test.R;
  3. importandroid.content.SharedPreferences;
  4. importandroid.os.Bundle;
  5. importandroid.preference.CheckBoxPreference;
  6. importandroid.preference.EditTextPreference;
  7. importandroid.preference.ListPreference;
  8. importandroid.preference.Preference;
  9. importandroid.preference.Preference.OnPreferenceChangeListener;
  10. importandroid.preference.Preference.OnPreferenceClickListener;
  11. importandroid.preference.PreferenceActivity;
  12. importandroid.preference.PreferenceManager;
  13. importandroid.preference.PreferenceScreen;
  14. importandroid.widget.Toast;
  15. publicclassPreferenceDemoActivityextendsPreferenceActivity
  16. implementsOnPreferenceChangeListener,OnPreferenceClickListener{
  17. privateListPreferencemList1Prefs;
  18. privateListPreferencemList2Prefs;
  19. privateCheckBoxPreferencemCheckPrefs;
  20. privateEditTextPreferencemEditPrefs;
  21. privateSharedPreferencesmSharedPrefs;
  22. /**Calledwhentheactivityisfirstcreated.*/
  23. @Override
  24. publicvoidonCreate(BundlesavedInstanceState){
  25. super.onCreate(savedInstanceState);
  26. addPreferencesFromResource(R.xml.preference);
  27. initViews();
  28. }
  29. privatevoidinitViews(){
  30. //得到以包命名的SharedPreferences
  31. mSharedPrefs=PreferenceManager.getDefaultSharedPreferences(this);
  32. mList1Prefs=(ListPreference)findPreference("key_call_config");
  33. mList2Prefs=(ListPreference)findPreference("key_msg_config");
  34. mCheckPrefs=(CheckBoxPreference)findPreference("switch");
  35. mEditPrefs=(EditTextPreference)findPreference("autoreply_text_cpntent");
  36. mList1Prefs.setOnPreferenceClickListener(this);
  37. mList1Prefs.setOnPreferenceChangeListener(this);
  38. mList2Prefs.setOnPreferenceChangeListener(this);
  39. mList2Prefs.setOnPreferenceClickListener(this);
  40. }
  41. @Override
  42. publicbooleanonPreferenceTreeClick(PreferenceScreenpreferenceScreen,
  43. Preferencepreference){
  44. if(preference==mEditPrefs){
  45. StringtoastStr=mEditPrefs.getTitle()+"\n"
  46. +"Content:"+mEditPrefs.getText();
  47. showToast(toastStr);
  48. }
  49. returnsuper.onPreferenceTreeClick(preferenceScreen,preference);
  50. }
  51. publicbooleanonPreferenceClick(Preferencepreference){
  52. StringprefsValue=mSharedPrefs.getString(preference.getKey(),"-1");
  53. showToast(prefsValue);
  54. returnfalse;
  55. }
  56. publicbooleanonPreferenceChange(Preferencepreference,ObjectnewValue){
  57. if(mList1Prefs==preference){
  58. StringprefsValue=mSharedPrefs.getString(preference.getKey(),"-1");
  59. showToast(prefsValue);
  60. }
  61. if(mList2Prefs==preference){
  62. StringprefsValue=newValue.toString();
  63. showToast(prefsValue);
  64. mList2Prefs.setValue(prefsValue);
  65. }
  66. returnfalse;
  67. }
  68. privatevoidshowToast(Stringarg){
  69. Toast.makeText(this,arg,Toast.LENGTH_SHORT).show();
  70. }
  71. }

程序原理:用一个ListPreference分别注册这两个监听器,然后用Tosat看他们在什么时候响应。../res/xml/preference文件如下:

[java] view plaincopy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <PreferenceScreenxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:title="@string/settings">
  4. <PreferenceCategory
  5.     android:title="@string/general_settings">
  6. <ListPreference
  7.        android:key="key_call_config"
  8. android:title="@string/incoming_call_come"
  9. android:dialogTitle="@string/incoming_call_come"
  10. android:entries="@array/response_entries"
  11. android:entryValues="@array/response_entry_values"/>
  12. <ListPreference
  13.        android:key="key_msg_config"
  14. android:title="@string/message_come"
  15. android:dialogTitle="@string/message_come"
  16. android:entries="@array/response_entries"
  17. android:entryValues="@array/response_entry_values"/>
  18. </PreferenceCategory>
  19. <PreferenceCategory
  20.      android:title="@string/user_defined_autoreply_settings">
  21. <CheckBoxPreference
  22.        android:title="@string/autoreply_switch"
  23. android:key="switch"/>
  24. <EditTextPreference
  25.        android:title="@string/user_defined_autoreply_text"
  26. android:key="autoreply_text_cpntent"
  27. android:dependency="switch"
  28. android:dialogTitle="@string/user_defined_autoreply_text"
  29. android:positiveButtonText="@android:string/ok"
  30. android:negativeButtonText="@android:string/cancel"/>
  31. </PreferenceCategory>
  32. </PreferenceScreen>

以下是ListPreference的Entries和EntryValues:

[html] view plaincopy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <resources>
  3. <string-arrayname="response_entries">
  4. <item>静音</item>
  5. <item>振动</item>
  6. <item>正常响铃</item>
  7. <item>LED灯亮</item>
  8. </string-array>
  9. <string-arrayname="response_entry_values">
  10. <item>0</item>
  11. <item>1</item>
  12. <item>2</item>
  13. <item>3</item>
  14. </string-array>
  15. </resources>

string.xml文件:

[html] view plaincopy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <resources>
  3. <stringname="hello">HelloWorld,PreferenceDemoActivity!</string>
  4. <stringname="app_name">PreferenceDemo</string>
  5. <stringname="settings">设置</string>
  6. <stringname="general_settings">常规设置</string>
  7. <stringname="incoming_call_come">来电时</string>
  8. <stringname="message_come">来短信时</string>
  9. <stringname="user_defined_autoreply_settings">自定义回复设置</string>
  10. <stringname="autoreply_switch">自动回复</string>
  11. <stringname="user_defined_autoreply_text">自动回复短信</string>
  12. </resources>

下面是Demo的主界面:


编译好,运行程序:点击mList1Prefs(来电时),Toast显示“-1”。再点击一个选项,对话框消失,Toast显示“-1”,为什么会这样?为什么不是第一次选中时的选项值?
其实,这是因为设置了OnPreferenceChangeListener。默认情况下,普通的ListPreference第一次选中一个值之后,Android框架会存贮好选中的值,下次打开,会默认选中上次选中的值,但是设置OnPreferenceChangeListener之后,值的存储就要自己来了,详见代码中的mList2Prefs.setValue();“来短信时”这一项就能够正常存贮选中的值。
现在区别就出来了:
OnPreferenceClickListener:是响应点击preference的事件,比如程序中,一点ListPreference,onPreferenceClick()中就弹出Toast。
OnPreferenceChangeListener:是响应preference的值被改变的事件(此时被改变的值需要自己存贮到SharedPreferences) ,比如程序中,点击ListPreference的某一项,onPreferenceChange()中就会弹出Toast。
另外:onPreferenceTreeClick()这个方法感觉和OnPreferenceClickListener的回调方法onPreferenceClick()的作用差不多,一样是响应点击的事件。
回头再看OnPreferenceChangeListener的文档:
Interface definition for a callback to be invoked when the value of this Preference has been changed by the user and is about to be set and/or persisted. This gives the client a chance to prevent setting and/or persisting the value.

就非常明白了~

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

PreferenceActivity

  PreferenceActivity是android提供的对系统信息和配置进行自动保存的Activity,它通过SharedPreference方式将信息保存在XML 文件当中。使用PreferenceActivity不需要我们对SharedPreference进行操作,系统会自动对Activity 的各种View上的改变进行保存(这个真是太赞了!)。   在android项目中添加一个 android xml 文件需要注意的是这次选择的是 Preference。而不是以往的Layout Android的SharedPreferences和PreferenceActivity用法_第1张图片 这个文件是保存在 res /xml 路径下的。

PreferenceScreen xml

  preference下的View是有限的,只有下面几个:
  • CheckBoxPreference:CheckBox选择项,对应的值的ture或flase
  • EditTextPreference:输入编辑框,值为String类型,会弹出对话框供输入。
  • ListPreference: 列表选择,弹出对话框供选择。
  • Preference:只进行文本显示,需要与其他进行组合使用。
  • PreferenceCategory:用于分组。
  • RingtonePreference:系统玲声选择
更多关于 PreferenceScreen的介绍可以查看博客园上的一篇文章:Android之PreferenceActivity [html] view plaincopy
  1. <prename="code"class="html"><prename="code"class="html"><?xmlversion="1.0"encoding="utf-8"?>
  2. <PreferenceScreenxmlns:android="http://schemas.android.com/apk/res/android">
  3. <CheckBoxPreferenceandroid:key="sounds"
  4. android:title="@string/play_sounds"android:summary="@string/play_sounds_summary"
  5. android:defaultValue="true"></CheckBoxPreference>
  6. <EditTextPreferenceandroid:key="warning_time"
  7. android:title="@string/warning_time"android:summary="@string/warning_time_summary"
  8. android:defaultValue="15"android:inputType="phone"android:digits="0123456789"></EditTextPreference>
  9. <CheckBoxPreferenceandroid:key="unlimited_participants"
  10. android:title="@string/unlimited_participants"android:summary="@string/unlimited_participants_summary"
  11. android:defaultValue="false"></CheckBoxPreference>
  12. <CheckBoxPreferenceandroid:key="variable_meeting_length"
  13. android:title="@string/variable_meeting_length"android:summary="@string/variable_meeting_length_summary"
  14. android:defaultValue="false"></CheckBoxPreference>
  15. </PreferenceScreen>
android:key 唯一标识符。它对应保存的XML保存的配置文件中的节点的 name属性 android:defaultValue 默认值,对应XML中的Value属性的值。 [java] view plaincopy
  1. /**
  2. *PreferenceActivity会自动保存更改
  3. */
  4. @Override
  5. protectedvoidonCreate(BundlesavedInstanceState){
  6. super.onCreate(savedInstanceState);
  7. this.addPreferencesFromResource(R.xml.setting);
  8. }

当PreferenceActivity上的View有所更改时,系统会自动将对应的值更新到XML配置文件中,该文件可以在android 的 file explorer 中的 data/data/"yourPageName"/shared_prefs/"yourpageName"_prefenrences.xml中找到。“yourpageName”表示你项目所在的包。

获取配置信息

  为了方便的获取配置信息,我们可以在PreferenceActivity里添加一些pulbic 方法来公开配置信息的访问。
[java] view plaincopy
  1. /**
  2. *获取是否播放声音
  3. */
  4. publicstaticbooleanplaySounds(Contextcontext){
  5. returnPreferenceManager.getDefaultSharedPreferences(context).getBoolean(SOUNDS,SOUNDS_DEFAULT);
  6. }
  7. /**
  8. *设置播放的声音
  9. *@paramcontext上下文
  10. *@paramvalue是否播放
  11. */
  12. publicstaticvoidsetPlaySounds(Contextcontext,booleanvalue){
  13. PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(SOUNDS,value).commit();
  14. }
  15. /**
  16. *获取警告时间
  17. *@paramcontext上下文
  18. *@return警告时间秒
  19. */
  20. publicstaticintgetWarningTime(Contextcontext){
  21. Stringvalue=PreferenceManager.getDefaultSharedPreferences(context).getString(WARNING_TIME,Integer.toString(WARNING_TIME_DEFAULT));
  22. try
  23. {
  24. returnInteger.parseInt(value);
  25. }
  26. catch(NumberFormatExceptione)
  27. {
  28. setWarningTime(context,WARNING_TIME_DEFAULT);
  29. returnWARNING_TIME_DEFAULT;
  30. }
  31. }
  32. /**
  33. *设置警告时间
  34. *@paramcontext上下文
  35. *@paramwarningTime警告时间
  36. */
  37. publicstaticvoidsetWarningTime(Contextcontext,intwarningTime){
  38. PreferenceManager.getDefaultSharedPreferences(context).edit().putString(WARNING_TIME,Integer.toString(warningTime)).commit();
  39. }
  40. /**
  41. *参加人数无限制
  42. *@paramcontext
  43. *@return
  44. */
  45. publicstaticbooleanallowUnlimitedParticipants(Contextcontext){
  46. returnPreferenceManager.getDefaultSharedPreferences(context).getBoolean(UNLIMITED_PARTICIPANTS,UNLIMITED_PARTICIPANTS_DEFAULT);
  47. }
  48. publicstaticvoidsetAllowUnlimitedParticipants(Contextcontext,booleanvalue){
  49. PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(UNLIMITED_PARTICIPANTS,value).commit();
  50. }
  51. /**
  52. *允许编辑会议时间
  53. *@paramcontext
  54. *@return
  55. */
  56. publicstaticbooleanallowVariableMeetingLength(Contextcontext){
  57. returnPreferenceManager.getDefaultSharedPreferences(context).getBoolean(VARIABLE_MEETING_LENGTH,VARIABLE_MEETING_LENGTH_DEFAULT);
  58. }
  59. publicstaticvoidsetAllowVariableMeetingLength(Contextcontext,booleanvalue){
  60. PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(VARIABLE_MEETING_LENGTH,value).commit();
  61. }

  getDefaultSharedPreferences(Context )用来获取preferences.以后的操作就和普通的Sharedpreferences一样了,如果需要修改某项配置的信息,记得最后需要 commit()。

当其他地方需要使用配置时,可以直接调用 setting.getXXX() 方法来获取配置信息。

系列索引

   Android 开源项目-StandupTimer学习笔记索引

更多相关文章

  1. EditView属性大全
  2. Android 利用 xml 文件实现 ImageView 的加载转圈动画
  3. android Service之四:传递复杂数据类型的远程服务

随机推荐

  1. Android学习之路(1) -- APK签名
  2. Android L / 5.0 帮助文档 API21文档 sam
  3. Android 入门文档_Android 4.0后JNI所做
  4. Android(安卓)澶嶄範_Processes and Thre
  5. Android尺寸单位含义及相互换算
  6. Android 蓝牙编程之 Java socket编程
  7. Android Linker 与 SO 加壳技术
  8. 深入解析android log的分析方法(1)
  9. Android的持续化集成及多版本打包
  10. Android软件安全开发实践--收藏