一、PreferenceFragment的引入:
PreferenceActivity是一个非常有用的基类,当我们开发Android项目时避免不了选项设置,这些设置习惯用Preference来保存。AnSEO靠我droid专门为这种Activity提供了便捷的基类PreferenceActivity。如果继承自Preference则不需要自己控制Preference的读写,PreferenceActivitySEO靠我会为我们处理一切。
PreferenceActivity与普通的Activity不同,它不是使用界面布局文件,而是使用选项设置的布局文件。
选项设置布局文件以PreferenceScreen作为根元素来表SEO靠我示定义一个参数设置界面布局。
从Android 3.0以后官方不再推荐直接让PreferenceActivity加载选项设置布局文件,而是建议使用PreferenceFragment,二者用法类似。所以SEO靠我今天就来学习一下。
下面的这张截图就是一个典型的例子:
我们会看到整个页面被分为几组:无线和网络、个人、账户、设备、系统。这个分组(或者叫分类)就是PreferenceCategory。
Wifi右边有开关SEO靠我,这一项就是CheckBoxPreference;其他还有ListPreference和EditTextPreference。
你的每一次设置,都会被Preference自动保存下来,这就是settinSEO靠我g的数据持久化。每个Preference都是以键值对的形式保存下来的。
PreferenceActivity的继承关系图:(不推荐使用)
PreferenceFragment的继承关系图:(推荐使用)
二、SEO靠我在XML文件中Preference的种类:
根节点中一定是<PreferenceScreen> 元素,在这个元素中可以添加不同的Preference。常见的Preference控件有:
直接子类:DialSEO靠我ogPreference, PreferenceGroup, RingtonePreference, TwoStatePreference 非直接子类: CheckBoxPrefereSEO靠我nce , EditTextPreference , ListPreference , MultiSelectListSEO靠我Preference, PreferenceCategory, PreferenceScreen, SwitchPreference我们还是通过实际的例子来实现吧。
【实例】
先新建一个工程文件:
新建类PSEO靠我refFragment.java,让其继承PreferenceFragment,并加载选项设置的布局文件:(核心代码是第6行和13行)
view source print ? 01. 1 packageSEO靠我 com.example.m05_preffragment01; 02. 2 03. 3 import android.os.Bundle; 04. 4 import android.preferenSEO靠我ce.PreferenceFragment; 05. 5 06. <strong> 6 public class PrefFragment extends PreferenceFragment { 0SEO靠我7. </strong> 7 @Override 08. 8 public void onCreate(Bundle savedInstanceState) { 09. 9 SEO靠我 // TODO Auto-generated method stub 10. 10 super.onCreate(savedInstanceState); 11. 11 SEO靠我 12. <strong>12 //从xml文件加载选项 13. 13 addPreferencesFromResource(R.xml.preferences)SEO靠我; 14. </strong>14 } 15. 15 }然后,在MainActivity.java中加载上面的Fragment:
view source print ? 01. 1 packagSEO靠我e com.example.m05_preffragment01; 02. 2 03. 3 import android.app.Activity; 04. 4 import android.app.SEO靠我FragmentManager; 05. 5 import android.app.FragmentTransaction; 06. 6 import android.os.Bundle; 07. 7SEO靠我 08. 8 public class MainActivity extends Activity { 09. 9 10. 10 @Override 11. 11 protected SEO靠我void onCreate(Bundle savedInstanceState) { 12. 12 super.onCreate(savedInstanceState); 13. 13SEO靠我 setContentView(R.layout.activity_main); 14. 14 15. 15 //加载PrefFragment 16. SEO靠我16 FragmentManager fragmentManager = getFragmentManager(); 17. 17 FragmentTransactioSEO靠我n transaction = fragmentManager.beginTransaction(); 18. 18 PrefFragment prefFragment = new PSEO靠我refFragment(); 19. 19 transaction.add(R.id.prefFragment, prefFragment); 20. 20 transSEO靠我action.commit(); 21. 21 22. 22 } 23. 23 24. 24 }接下来的知识就是重头戏了,既然PrefFragment要加载选项设置的布SEO靠我局文件R.xml.preferences,那我们就来定义一下这个preferences.xml:
在res目录下新建立一个xml目录,在该目录中新建文件preferences.xml:
关于prefereSEO靠我nces.xml的文件里面的代码,请看下面这一段。
五、preference详解:
1、<PreferenceCategory>的方式进行分组:
preferences.xml举例如下:
view sourcSEO靠我e print ? 01. <?xml version=1.0 encoding=utf-8?> 02. <PreferenceScreen xmlns:android=http://schemas.SEO靠我android.com/apk/res/android > 03. 04. <!-- 设置的类别 --> 05. <PreferenceCategory 06. android:key=mylocSEO靠我ation 07. android:summary=我的位置 08. android:title=我的位置源> 09. <CheckBoxPreference 10. andSEO靠我roid:key=wireless_network 11. android:summary=使用<a href="http://www.it165.net/network/nwwx/" target=SEO靠我"_blank" class="keylink">无线网络</a>查看应用程序中的位置 12. android:title=使用<a href="http://www.it165.net/networSEO靠我k/nwwx/" target="_blank" class="keylink">无线网络</a>/> 13. </PreferenceCategory> 14. 15. <PrSEO靠我eferenceCategory 16. android:key=mymsg 17. android:summary=个人信息 18. android:title=个人信息> SEO靠我 19. <EditTextPreference 20. android:key=myname 21. android:title=请输入真实姓名 22. android:summary=姓名/> SEO靠我 23. </PreferenceCategory> 24. 25. </PreferenceScreen>上方代码中,一个<PreferenceCategory>就是一个类别SEO靠我,单个的<PreferenceCategory>可以放入任意的Preference控件。我们在第一个类别中放入了CheckBoxPreference控件,在第二个类别中放入了EditTextPrefeSEO靠我rence控件。运行效果如下:
运行时候,会自动在/data/data/<packagename>/shared_prefs/目录生成一个文本文件:
注:这个文本的文件名太长了,我们可以在上方PrefFrSEO靠我agment.java的第13行代码后面加上这样一句话来修改文件名:(这里我将文件名修改为:mysetting)
view source print ? 1. getPreferenceManager(SEO靠我).setSharedPreferencesName(mysetting);文本内容如下:
我们现在在CheckBoxPreference中打钩,然后在EditTextPreference中输入内容:
文SEO靠我本内容显示如下:
2、显示子屏幕subscreens方式的进行分组:
view source print ? 01. 1 <?xml version=1.0 encoding=UTF-8?> 02. 2 SEO靠我<PreferenceScreen xmlns:android=http://schemas.android.com/apk/res/android 03. 3 android:title=SSEO靠我ettings > 04. 4 05. 5 <PreferenceScreen 06. 6 xmlns:android=http://schemas.android.com/aSEO靠我pk/res/android 07. 7 android:summary=settings about emotions 08. 8 android:title=EmoSEO靠我tions > 09. 9 <CheckBoxPreference 10. 10 android:defaultValue=true 11. 11 SEO靠我 android:summaryOff=No,I am sorry. 12. 12 android:summaryOn=Yes,I love you! 13. 13 SEO靠我 android:title=Love me? > 14. 14 </CheckBoxPreference> 15. 15 <CheckBoxPrSEO靠我eference 16. 16 android:defaultValue=false 17. 17 android:summaryOff=No,you SEO靠我are a good person. 18. 18 android:summaryOn=Yes,I hate you! 19. 19 android:tSEO靠我itle=Hate me? > 20. 20 </CheckBoxPreference> 21. 21 </PreferenceScreen> 22. 22 23. 2SEO靠我3 <PreferenceScreen 24. 24 xmlns:android=http://schemas.android.com/apk/res/android 25. SEO靠我25 android:summary=settings about relations 26. 26 android:title=Relations > 27. 27 SEO靠我 <CheckBoxPreference 28. 28 android:defaultValue=true 29. 29 android:SEO靠我summaryOff=No,I am sorry. 30. 30 android:summaryOn=Yes,we are family! 31. 31 SEO靠我 android:title=Family? > 32. 32 </CheckBoxPreference> 33. 33 <CheckBoxPreference 34.SEO靠我 34 android:defaultValue=false 35. 35 android:summaryOff=No,I am sorry. 36. SEO靠我36 android:summaryOn=Yes,we are friends! 37. 37 android:title=Friends? > 38.SEO靠我 38 </CheckBoxPreference> 39. 39 </PreferenceScreen> 40. 40 41. 41 </PreferenceScreen>运行SEO靠我效果如下:
点击上方第一个preference,进入下图中左侧界面;点击上方第二个preference,进入下图中右侧界面。效果如下:
3、ListPreference控件:
点击该控件后,将列出一个单选按SEO靠我钮的列表。用法如下:
view source print ? 01. <?xml version=1.0 encoding=utf-8?> 02. <PreferenceScreen xmlns:andSEO靠我roid=http://schemas.android.com/apk/res/android > 03. 04. <PreferenceCategory 05. android:key=myloSEO靠我cation 06. android:summary=我的位置 07. android:title=我的位置源> 08. <ListPreference 09. android:key=myciSEO靠我ties 10. android:title=所属城市 11. android:summary=点击弹出城市列表 12. android:dialogTitle=请选择城市 13. android:eSEO靠我ntries=@array/cities 14. android:entryValues=@array/cities/> 15. </PreferenceCategory> 16. 17. </PSEO靠我referenceScreen>上方代码中,PreferenceScreen为根标签,ListPreference为子标签。ListPreference的常见属性如下:
android:key 唯一标识SEO靠我符,和android:id相类似,PreferenceManager可以以其为参数通过findPreference获取指定的preference 。 注意,这个android:key的值也是PrefeSEO靠我rence文件里面的XML“键”名 android:title 大标题 android:summary 标题下面的小字(这个要作为选项卡才有) android:entries 弹出的对话框中,列表显示SEO靠我的文本内容,注意哦,这里指定的是一个数组。 android:entryValues 与android:entries相对应的值 android:defaultValue 当对应值不存在时的默认值 anSEO靠我droid:dialogTitle 弹出的对话框中的标题信息关于android:entries和android:entryValues的区别,要强调一下:
android:entries SEO靠我 :The human-readable array to present as a list. 是展现给用户的列表的值。 android:entryValues SEO靠我:he array to find the value to save for a preference when an entry from entries is selected. 展现的用户的选SEO靠我择列表的每个元素选择后,需要存储到手机中,这里的entryValues就是列表中各个元素被选择后存储到手机中的值(通过sharedPreferences保存在/data/data/<packagenaSEO靠我me>/shared_prefs/目录下)。简单的说就是此处是数据库中的值。上面的android:entries是展现给用户的列表的值。我们在上方代码中的第13、14行引用了数据,紧接着我们要在valSEO靠我ues目录下的strings.xml文件中定义这个被引用的城市列表(即数据来源):
view source print ? 01. 1 <?xml version=1.0 encoding=utf-8?SEO靠我> 02. 2 <resources> 03. 3 04. 4 <string name=app_name>m05_PrefFragment01</string> 05. 5 <strSEO靠我ing name=action_settings>Settings</string> 06. 6 <string name=hello_world>Hello world!</string> SEO靠我07. 7 08. <strong> 8 <string-array name=cities> 09. 9 <item>成都</item> 10. 10 <itSEO靠我em>重庆</item> 11. 11 <item>黄冈</item> 12. 12 </string-array></strong> 13. 13 14. 14 </resoSEO靠我urces>上方代码中,8至12行:即加粗部分,是我添加的数据源。
运行程序效果如下:
六、监听事件onPreferenceTreeClick()方法:
view source print ? 1. pubSEO靠我lic boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen Preference preference)当任何一个prefeSEO靠我rence控件被点击,都将触发该方法。但是可以通过preference.getKey()这个方法找到具体是哪个preference被点击了,因为每个preference的key都是唯一的。
【实例】
现将SEO靠我preferences.xml这个设置选项的布局文件,定义如下:
view source print ? 01. <?xml version=1.0 encoding=utf-8?> 02. <PrefSEO靠我erenceScreen xmlns:android=http://schemas.android.com/apk/res/android > 03. 04. <!-- 设置的类别 --> 05.SEO靠我 <PreferenceCategory 06. android:key=mylocation 07. android:summary=我的位置 08. android:title=我的位置源 > 0SEO靠我9. <CheckBoxPreference 10. android:key=wireless_network 11. android:summary=使用无线网络查看应用程序(例如Google地图)SEO靠我中的位置 12. android:title=使用无线网络 /> 13. <CheckBoxPreference 14. android:key=gps_satellite_setting 15. aSEO靠我ndroid:summary=定位时,精确到街道级别(取消选择可节约电量) 16. android:title=启用GPS卫星设置 /> 17. </PreferenceCategory> 18. SEO靠我 19. <PreferenceCategory 20. android:key=mymessage 21. android:summary=个人信息设置 22. android:title=个人信息SEO靠我设置 > 23. <CheckBoxPreference 24. android:key=yesno_save_individual_info 25. android:title=是否保存个人信息 /SEO靠我> 26. <EditTextPreference 27. android:key=individual_name 28. android:summary=请输入真实姓名 29. android:tiSEO靠我tle=姓名 /> 30. <ListPreference 31. android:entries=@array/cities 32. android:entryValues=@array/citiSEO靠我es 33. android:key=mycity 34. android:summary=所属城市 35. android:title=所属城市 /> 36. </PreferenceCategorSEO靠我y> 37. 38. </PreferenceScreen>运行效果如下:
现在我们需要做的是,选中上方红框中的CheckBoxPreference,对应下面的EditTextPreference为SEO靠我编辑状态;否则,如果CheckBoxPreference没有被选中,则EditTextPreference为不可编辑状态。修改PrefFragment.java的代码,其完整版代码如下:
view soSEO靠我urce print ? 01. 1 package com.example.m05_preffragment01; 02. 2 03. 3 import android.os.Bundle; 04.SEO靠我 4 import android.preference.CheckBoxPreference; 05. 5 import android.preference.EditTextPreference;SEO靠我 06. 6 import android.preference.Preference; 07. 7 import android.preference.PreferenceFragment; 08.SEO靠我 8 import android.preference.PreferenceScreen; 09. 9 10. 10 public class PrefFragment extends PreferSEO靠我enceFragment { 11. 11 12. 12 @Override 13. 13 public void onCreate(Bundle savedInstanceStateSEO靠我) { 14. 14 // TODO Auto-generated method stub 15. 15 super.onCreate(savedInstanceStaSEO靠我te); 16. 16 17. 17 //从xml文件加载选项 18. 18 addPreferencesFromResource(R.xml.prefSEO靠我erences); 19. 19 } 20. 20 21. 21 @Override 22. 22 public boolean onPreferenceTreeCliSEO靠我ck(PreferenceScreen preferenceScreen, 23. 23 Preference preference) { 24. 24 //如SEO靠我果“保存个人信息”这个按钮被选中,将进行括号里面的操作 25. 25 if(yesno_save_individual_info.equals(preference.getKey())SEO靠我) { 26. 26 CheckBoxPreference checkBoxPreference = (CheckBoxPreference)findPrSEO靠我eference(yesno_save_individual_info); 27. 27 EditTextPreference editTextPreference = (EdSEO靠我itTextPreference)findPreference(individual_name); 28. 28 //让editTextPreference和checkBoxPSEO靠我reference的状态保持一致 29. 29 editTextPreference.setEnabled(checkBoxPreference.isChecked()); 3SEO靠我0. 30 } 31. 31 // TODO Auto-generated method stub 32. 32 return super.onPrefSEO靠我erenceTreeClick(preferenceScreen, preference); 33. 33 } 34. 34 }代码解释:
当任何一个preference控件被点击,都将触发onSEO靠我PreferenceTreeClick()方法(22行),但是可以通过preference.getKey()这个方法找到具体是哪个preference被点击(25行)。
26行、27行:通过publicSEO靠我 Preference findPreference(CharSequence key)找到对应的preference,然后强转为它的子类。
29行:核心代码,让editTextPreference和cSEO靠我heckBoxPreference的状态保持一致。
运行效果如下:
这样,我们的功能就实现了。
网站备案号:浙ICP备17034767号-2