天天看点

Android数据存储(二)----PreferenceFragment详解

【正文】

一、preferencefragment的引入:

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

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

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

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

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

Android数据存储(二)----PreferenceFragment详解

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

wifi右边有开关,这一项就是checkboxpreference;其他还有listpreference和edittextpreference。

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

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

Android数据存储(二)----PreferenceFragment详解

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

Android数据存储(二)----PreferenceFragment详解

二、在xml文件中preference的种类:

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

直接子类:dialogpreference, preferencegroup, ringtonepreference, twostatepreference

非直接子类:checkboxpreference, edittextpreference, listpreference, multiselectlistpreference, preferencecategory, preferencescreen, switchpreference

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

【实例】

先新建一个工程文件:

Android数据存储(二)----PreferenceFragment详解

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

Android数据存储(二)----PreferenceFragment详解
Android数据存储(二)----PreferenceFragment详解

然后,在mainactivity.java中加载上面的fragment:

Android数据存储(二)----PreferenceFragment详解
Android数据存储(二)----PreferenceFragment详解

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

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

Android数据存储(二)----PreferenceFragment详解

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

五、preference详解:

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

preferences.xml举例如下:

Android数据存储(二)----PreferenceFragment详解
Android数据存储(二)----PreferenceFragment详解

上方代码中,一个<preferencecategory>就是一个类别,单个的<preferencecategory>可以放入任意的preference控件。我们在第一个类别中放入了checkboxpreference控件,在第二个类别中放入了edittextpreference控件。运行效果如下:

Android数据存储(二)----PreferenceFragment详解

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

Android数据存储(二)----PreferenceFragment详解

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

文本内容如下:

Android数据存储(二)----PreferenceFragment详解

我们现在在checkboxpreference中打钩,然后在edittextpreference中输入内容:

Android数据存储(二)----PreferenceFragment详解

文本内容显示如下:

Android数据存储(二)----PreferenceFragment详解

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

Android数据存储(二)----PreferenceFragment详解
Android数据存储(二)----PreferenceFragment详解

运行效果如下:

Android数据存储(二)----PreferenceFragment详解

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

Android数据存储(二)----PreferenceFragment详解
Android数据存储(二)----PreferenceFragment详解

3、listpreference控件:

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

Android数据存储(二)----PreferenceFragment详解
Android数据存储(二)----PreferenceFragment详解

上方代码中,preferencescreen为根标签,listpreference为子标签。listpreference的常见属性如下:

android:key 唯一标识符,和android:id相类似,preferencemanager可以以其为参数通过findpreference获取指定的preference 。 注意,这个android:key的值也是preference文件里面的xml“键”名

android:title 大标题

android:summary 标题下面的小字(这个要作为选项卡才有)

android:entries 弹出的对话框中,列表显示的文本内容,注意哦,这里指定的是一个数组。

android:entryvalues 与android:entries相对应的值

android:defaultvalue 当对应值不存在时的默认值

android:dialogtitle 弹出的对话框中的标题信息

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

android:entries:the human-readable array to present as a list. 是展现给用户的列表的值。

android:entryvalues :he array to find the value to save for a preference when an entry from entries is selected. 展现的用户的选择列表的每个元素选择后,需要存储到手机中,这里的entryvalues就是列表中各个元素被选择后存储到手机中的值(通过sharedpreferences保存在/data/data/<packagename>/shared_prefs/目录下)。简单的说就是此处是数据库中的值。上面的android:entries是展现给用户的列表的值。

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

Android数据存储(二)----PreferenceFragment详解
Android数据存储(二)----PreferenceFragment详解

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

运行程序效果如下:

Android数据存储(二)----PreferenceFragment详解
Android数据存储(二)----PreferenceFragment详解

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

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

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

Android数据存储(二)----PreferenceFragment详解
Android数据存储(二)----PreferenceFragment详解
Android数据存储(二)----PreferenceFragment详解

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

Android数据存储(二)----PreferenceFragment详解
Android数据存储(二)----PreferenceFragment详解

代码解释:

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

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

29行:核心代码,让edittextpreference和checkboxpreference的状态保持一致。

Android数据存储(二)----PreferenceFragment详解
Android数据存储(二)----PreferenceFragment详解

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