解决方案

Android之PreferenceFragment详解

seo靠我 2023-09-26 03:26:27

【正文】

一、PreferenceFragment的引入:

PreferenceActivity是一个非常有用的基类,当我们开发Android项目时避免不了选项设置,这些设置习惯用Preference来保SEO靠我存。Android专门为这种Activity提供了便捷的基类PreferenceActivity。如果继承自Preference则不需要自己控制Preference的读写,PreferenceActiSEO靠我vity会为我们处理一切。

PreferenceActivity与普通的Activity不同,它不是使用界面布局文件,而是使用选项设置的布局文件。

选项设置布局文件以PreferenceScreen作为根SEO靠我元素来表示定义一个参数设置界面布局。

从Android 3.0以后官方不再推荐直接让PreferenceActivity加载选项设置布局文件,而是建议使用PreferenceFragment,二者用法类SEO靠我似。所以今天就来学习一下。

下面的这张截图就是一个典型的例子:

我们会看到整个页面被分为几组:无线和网络、个人、账户、设备、系统。这个分组(或者叫分类)就是PreferenceCategory。

Wifi右SEO靠我边有开关,这一项就是CheckBoxPreference;其他还有ListPreference和EditTextPreference。

你的每一次设置,都会被Preference自动保存下来,这就是seSEO靠我tting的数据持久化。每个Preference都是以键值对的形式保存下来的。

PreferenceActivity的继承关系图:(不推荐使用)

PreferenceFragment的继承关系图:(推荐使SEO靠我用)

二、在XML文件中Preference的种类:

根节点中一定是<PreferenceScreen> 元素,在这个元素中可以添加不同的Preference。常见的Preference控件有:

直接子类:SEO靠我DialogPreference, PreferenceGroup, RingtonePreference, TwoStatePreference非直接子类:CheckBoxPreference, ESEO靠我ditTextPreference, ListPreference, MultiSelectListPreference, PreferenceCategory, PreferenceScreen, SEO靠我SwitchPreference

我们还是通过实际的例子来实现吧。 

【实例】

先新建一个工程文件:

新建类PrefFragment.java,让其继承PreferenceFragment,并加载选项设置的布局SEO靠我文件:(核心代码是第6行和13行)

1 package com.example.m05_preffragment01; 2 3 import android.os.BunSEO靠我dle; 4 import android.preference.PreferenceFragment; 5 6 public class PrefFrSEO靠我agment extends PreferenceFragment { 7 @Override 8 public void onCreate(Bundle savedISEO靠我nstanceState) { 9 // TODO Auto-generated method stub 10 super.onCreate(savedInstanceSEO靠我State); 11 12 //从xml文件加载选项 13 addPreferencesFromResource(R.xml.preferences);SEO靠我 14 } 15 }

然后,在MainActivity.java中加载上面的Fragment:

1 package com.example.m05_preffragmentSEO靠我01; 2 3 import android.app.Activity; 4 import android.app.FragmentManager; SEO靠我 5 import android.app.FragmentTransaction; 6 import android.os.Bundle; 7 SEO靠我 8 public class MainActivity extends Activity { 9 10 @Override 11 protecteSEO靠我d void onCreate(Bundle savedInstanceState) { 12 super.onCreate(savedInstanceState); SEO靠我13 setContentView(R.layout.activity_main); 14 15 //加载PrefFragment 16 FragmenSEO靠我tManager fragmentManager = getFragmentManager(); 17 FragmentTransaction transaction = fragmeSEO靠我ntManager.beginTransaction(); 18 PrefFragment prefFragment = new PrefFragment(); 19 SEO靠我transaction.add(R.id.prefFragment, prefFragment); 20 transaction.commit(); 21 SEO靠我 22 } 23 24 }

接下来的知识就是重头戏了,既然PrefFragment要加载选项设置的布局文件R.xml.preferences,那我们就来定义一下这个prSEO靠我eferences.xml:

在res目录下新建立一个xml目录,在该目录中新建文件preferences.xml:

关于preferences.xml的文件里面的代码,请看下面这一段。

五、prefereSEO靠我nce详解:

1、<PreferenceCategory>的方式进行分组:

preferences.xml举例如下:

<?xml version="1.0" encoding="utf-8"?> SEO靠我 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" ><!-- 设置的类别 --><PrefSEO靠我erenceCategory android:key="mylocation"android:summary="我的位置"android:title="我的位置源"> <CheckBoxPrefereSEO靠我nce android:key="wireless_network"android:summary="使用无线网络查看应用程序中的位置"android:title="使用无线网络"/> </PrefeSEO靠我renceCategory><PreferenceCategory android:key="mymsg"android:summary="个人信息"android:title="个人信息"> <EdSEO靠我itTextPreference android:key="myname"android:title="请输入真实姓名"android:summary="姓名"/> </PreferenceCategSEO靠我ory> </PreferenceScreen>

上方代码中,一个<PreferenceCategory>就是一个类别,单个的<PreferenceCategory>可以放入任意的Preference控SEO靠我件。我们在第一个类别中放入了CheckBoxPreference控件,在第二个类别中放入了EditTextPreference控件。运行效果如下:

运行时候,会自动在/data/data/<packagSEO靠我ename>/shared_prefs/目录生成一个文本文件:

注:这个文本的文件名太长了,我们可以在上方PrefFragment.java的第13行代码后面加上这样一句话来修改文件名:(这里我将文件名SEO靠我修改为:mysetting)

getPreferenceManager().setSharedPreferencesName("mysetting");

文本内容如下:

我们现在在CheckBoxPrefeSEO靠我rence中打钩,然后在EditTextPreference中输入内容:

文本内容显示如下:

2、显示子屏幕subscreens方式的进行分组:

1 <?xml version="1.0" encodingSEO靠我="UTF-8"?> 2 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" SEO靠我 3 android:title="Settings" > 4 5 <PreferenceScreen 6 xmlns:android="htSEO靠我tp://schemas.android.com/apk/res/android" 7 android:summary="settings about emotions" SEO靠我 8 android:title="Emotions" > 9 <CheckBoxPreference 10 android:defaultValue="true" SEO靠我 11 android:summaryOff="No,I am sorry." 12 android:summaryOn="Yes,I love you!" SEO靠我 13 android:title="Love me?" > 14 </CheckBoxPreference> 15 <CheckBoxPreference SEO靠我 16 android:defaultValue="false" 17 android:summaryOff="No,you are a good person." SEO靠我 18 android:summaryOn="Yes,I hate you!" 19 android:title="Hate me?" > 20 </CheckBoxSEO靠我Preference> 21 </PreferenceScreen> 22 23 <PreferenceScreen 24 xmlns:SEO靠我android="http://schemas.android.com/apk/res/android" 25 android:summary="settings about relaSEO靠我tions" 26 android:title="Relations" > 27 <CheckBoxPreference 28 android:defaSEO靠我ultValue="true" 29 android:summaryOff="No,I am sorry." 30 android:summaryOn="Yes,we SEO靠我are family!" 31 android:title="Family?" > 32 </CheckBoxPreference> 33 <CheckSEO靠我BoxPreference 34 android:defaultValue="false" 35 android:summaryOff="No,I am sorry."SEO靠我 36 android:summaryOn="Yes,we are friends!" 37 android:title="Friends?" > 38SEO靠我 </CheckBoxPreference> 39 </PreferenceScreen> 40 41 </PreferenceScreen>

运行效果如SEO靠我下:

点击上方第一个preference,进入下图中左侧界面;点击上方第二个preference,进入下图中右侧界面。效果如下:

3、ListPreference控件:

点击该控件后,将列出一个单选按钮的列SEO靠我表。用法如下:

<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemaSEO靠我s.android.com/apk/res/android" ><PreferenceCategory android:key="mylocation"android:summary="我的位置"anSEO靠我droid:title="我的位置源"> <ListPreference android:key="mycities"android:title="所属城市"android:summary="点击弹出SEO靠我城市列表"android:dialogTitle="请选择城市"android:entries="@array/cities"android:entryValues="@array/cities"/>SEO靠我</PreferenceCategory></PreferenceScreen>

上方代码中,PreferenceScreen为根标签,ListPreference为子标签。ListPreferenceSEO靠我的常见属性如下:

android:key 唯一标识符,和android:id相类似,PreferenceManager可以以其为参数通过findPreference获取指定的preference 。 注SEO靠我意,这个android:key的值也是Preference文件里面的XML“键”名 android:title 大标题android:summary 标题下面的小字(这个要作为选项卡才有)androiSEO靠我d:entries 弹出的对话框中,列表显示的文本内容,注意哦,这里指定的是一个数组。android:entryValues 与android:entries相对应的值android:defaultVSEO靠我alue 当对应值不存在时的默认值android:dialogTitle 弹出的对话框中的标题信息

关于android:entries和android:entryValues的区别,要强调一下:

andrSEO靠我oid:entries:The human-readable array to present as a list. 是展现给用户的列表的值。android:entryValues :he arraySEO靠我 to find the value to save for a preference when an entry from entries is selected. 展现的用户的选择列表的每个元素选SEO靠我择后,需要存储到手机中,这里的entryValues就是列表中各个元素被选择后存储到手机中的值(通过sharedPreferences保存在/data/data/<packagename>/shareSEO靠我d_prefs/目录下)。简单的说就是此处是数据库中的值。上面的android:entries是展现给用户的列表的值。

我们在上方代码中的第13、14行引用了数据,紧接着我们要在values目录下的stSEO靠我rings.xml文件中定义这个被引用的城市列表(即数据来源):

1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> SEO靠我 3 4 <string name="app_name">m05_PrefFragment01</string> 5 <string name="action_seSEO靠我ttings">Settings</string> 6 <string name="hello_world">Hello world!</string> 7 SEO靠我 8 <string-array name="cities"> 9 <item>成都</item> 10 <item>重庆</item> 11 <iSEO靠我tem>黄冈</item> 12 </string-array> 13 14 </resources>

上方代码中,8至12行:即加粗部分,是我添加的数据SEO靠我源。

运行程序效果如下:

六、监听事件onPreferenceTreeClick()方法:

public boolean onPreferenceTreeClick(PreferenceScreen preSEO靠我ferenceScreen Preference preference)

当任何一个preference控件被点击,都将触发该方法。但是可以通过preference.getKey()这个方法找到具体是哪SEO靠我个preference被点击了,因为每个preference的key都是唯一的。

【实例】

现将preferences.xml这个设置选项的布局文件,定义如下:

<?xml version="1.0" enSEO靠我coding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/androidSEO靠我" ><!-- 设置的类别 --><PreferenceCategoryandroid:key="mylocation"android:summary="我的位置"android:title="我的位SEO靠我置源" ><CheckBoxPreferenceandroid:key="wireless_network"android:summary="使用无线网络查看应用程序(例如Google地图)中的位置"SEO靠我android:title="使用无线网络" /><CheckBoxPreferenceandroid:key="gps_satellite_setting"android:summary="定位时,SEO靠我精确到街道级别(取消选择可节约电量)"android:title="启用GPS卫星设置" /></PreferenceCategory><PreferenceCategoryandroid:key="SEO靠我mymessage"android:summary="个人信息设置"android:title="个人信息设置" ><CheckBoxPreferenceandroid:key="yesno_saveSEO靠我_individual_info"android:title="是否保存个人信息" /><EditTextPreferenceandroid:key="individual_name"android:SEO靠我summary="请输入真实姓名"android:title="姓名 " /><ListPreferenceandroid:entries="@array/cities"android:entryVaSEO靠我lues="@array/cities"android:key="mycity"android:summary="所属城市"android:title="所属城市" /></PreferenceCatSEO靠我egory></PreferenceScreen>

运行效果如下:

现在我们需要做的是,选中上方红框中的CheckBoxPreference,对应下面的EditTextPreference为编辑状态;否则SEO靠我,如果CheckBoxPreference没有被选中,则EditTextPreference为不可编辑状态。修改PrefFragment.java的代码,其完整版代码如下:

1 package com.SEO靠我example.m05_preffragment01; 2 3 import android.os.Bundle; 4 import android.pSEO靠我reference.CheckBoxPreference; 5 import android.preference.EditTextPreference; 6 impoSEO靠我rt android.preference.Preference; 7 import android.preference.PreferenceFragment; 8 SEO靠我import android.preference.PreferenceScreen; 9 10 public class PrefFragment extends PSEO靠我referenceFragment { 11 12 @Override 13 public void onCreate(Bundle savedInstSEO靠我anceState) { 14 // TODO Auto-generated method stub 15 super.onCreate(savedInstanceStSEO靠我ate); 16 17 //从xml文件加载选项 18 addPreferencesFromResource(R.xml.preferences); SEO靠我 19 } 20 21 @Override 22 public boolean onPreferenceTreeClick(PreferenSEO靠我ceScreen preferenceScreen, 23 Preference preference) { 24 //如果“保存个人信息”这个按钮被选中,将进行括号里SEO靠我面的操作 25 if("yesno_save_individual_info".equals(preference.getKey())) { 26 CheckBoxPrSEO靠我eference checkBoxPreference = (CheckBoxPreference)findPreference("yesno_save_individual_info"); SEO靠我 27 EditTextPreference editTextPreference = (EditTextPreference)findPreference("individual_name")SEO靠我; 28 //让editTextPreference和checkBoxPreference的状态保持一致 29 editTextPreference.setEnableSEO靠我d(checkBoxPreference.isChecked()); 30 } 31 // TODO Auto-generated method stub SEO靠我 32 return super.onPreferenceTreeClick(preferenceScreen, preference); 33 } 34 }

代码解释SEO靠我

当任何一个preference控件被点击,都将触发onPreferenceTreeClick()方法(22行),但是可以通过preference.getKey()这个方法找到具体是哪个prefereSEO靠我nce被点击(25行)。

26行、27行:通过public Preference findPreference(CharSequence key)找到对应的preference,然后强转为它的子类。

29SEO靠我行:核心代码,让editTextPreference和checkBoxPreference的状态保持一致。

运行效果如下:

这样,我们的功能就实现了。

本文转自:http://www.cnblogs.comSEO靠我/smyhvae/p/4020469.html

“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2