Android数据存储(二)----PreferenceFragment详解
【声明】
欢迎转载,但请保留文章原始出处→_→
生命壹号:http://www.cnblogs.com/smyhvae/
文章来源:http://www.cnblogs.com/smyhvae/p/4020469.html
【正文】
一、PreferenceFragment的引入:
PreferenceActivity是一个非常有用的基类,当我们开发Android项目时避免不了选项设置,这些设置习惯用Preference来保存。Android专门为这种Activity提供了便捷的基类PreferenceActivity。如果继承自Preference则不需要自己控制Preference的读写,PreferenceActivity会为我们处理一切。
PreferenceActivity与普通的Activity不同,它不是使用界面布局文件,而是使用选项设置的布局文件。
选项设置布局文件以PreferenceScreen作为根元素来表示定义一个参数设置界面布局。
从Android 3.0以后官方不再推荐直接让PreferenceActivity加载选项设置布局文件,而是建议使用PreferenceFragment,二者用法类似。所以今天就来学习一下。
下面的这张截图就是一个典型的例子:

我们会看到整个页面被分为几组:无线和网络、个人、账户、设备、系统。这个分组(或者叫分类)就是PreferenceCategory。
Wifi右边有开关,这一项就是CheckBoxPreference;其他还有ListPreference和EditTextPreference。
你的每一次设置,都会被Preference自动保存下来,这就是setting的数据持久化。每个Preference都是以键值对的形式保存下来的。
PreferenceActivity的继承关系图:(不推荐使用)

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

二、在XML文件中Preference的种类:
根节点中一定是<PreferenceScreen> 元素,在这个元素中可以添加不同的Preference。常见的Preference控件有:
- 直接子类:DialogPreference, PreferenceGroup, RingtonePreference, TwoStatePreference
- 非直接子类:CheckBoxPreference, EditTextPreference, ListPreference, MultiSelectListPreference, PreferenceCategory, PreferenceScreen, SwitchPreference
我们还是通过实际的例子来实现吧。
【实例】
先新建一个工程文件:

新建类PrefFragment.java,让其继承PreferenceFragment,并加载选项设置的布局文件:(核心代码是第6行和13行)
package com.example.m05_preffragment01; import android.os.Bundle;
import android.preference.PreferenceFragment; public class PrefFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState); //从xml文件加载选项
addPreferencesFromResource(R.xml.preferences);
}
}
然后,在MainActivity.java中加载上面的Fragment:
package com.example.m05_preffragment01; import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //加载PrefFragment
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
PrefFragment prefFragment = new PrefFragment();
transaction.add(R.id.prefFragment, prefFragment);
transaction.commit(); } }
接下来的知识就是重头戏了,既然PrefFragment要加载选项设置的布局文件R.xml.preferences,那我们就来定义一下这个preferences.xml:
在res目录下新建立一个xml目录,在该目录中新建文件preferences.xml:

关于preferences.xml的文件里面的代码,请看下面这一段。
五、preference详解:
1、<PreferenceCategory>的方式进行分组:
preferences.xml举例如下:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <!-- 设置的类别 -->
<PreferenceCategory
android:key="mylocation"
android:summary="我的位置"
android:title="我的位置源">
<CheckBoxPreference
android:key="wireless_network"
android:summary="使用无线网络查看应用程序中的位置"
android:title="使用无线网络"/>
</PreferenceCategory> <PreferenceCategory
android:key="mymsg"
android:summary="个人信息"
android:title="个人信息">
<EditTextPreference
android:key="myname"
android:title="请输入真实姓名"
android:summary="姓名"/>
</PreferenceCategory> </PreferenceScreen>
上方代码中,一个<PreferenceCategory>就是一个类别,单个的<PreferenceCategory>可以放入任意的Preference控件。我们在第一个类别中放入了CheckBoxPreference控件,在第二个类别中放入了EditTextPreference控件。运行效果如下:

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

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

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

文本内容显示如下:

2、显示子屏幕subscreens方式的进行分组:
<?xml version="1.0" encoding="UTF-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="Settings" > <PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:summary="settings about emotions"
android:title="Emotions" >
<CheckBoxPreference
android:defaultValue="true"
android:summaryOff="No,I am sorry."
android:summaryOn="Yes,I love you!"
android:title="Love me?" >
</CheckBoxPreference>
<CheckBoxPreference
android:defaultValue="false"
android:summaryOff="No,you are a good person."
android:summaryOn="Yes,I hate you!"
android:title="Hate me?" >
</CheckBoxPreference>
</PreferenceScreen> <PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:summary="settings about relations"
android:title="Relations" >
<CheckBoxPreference
android:defaultValue="true"
android:summaryOff="No,I am sorry."
android:summaryOn="Yes,we are family!"
android:title="Family?" >
</CheckBoxPreference>
<CheckBoxPreference
android:defaultValue="false"
android:summaryOff="No,I am sorry."
android:summaryOn="Yes,we are friends!"
android:title="Friends?" >
</CheckBoxPreference>
</PreferenceScreen> </PreferenceScreen>
运行效果如下:

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


3、ListPreference控件:
点击该控件后,将列出一个单选按钮的列表。用法如下:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <PreferenceCategory
android:key="mylocation"
android:summary="我的位置"
android:title="我的位置源">
<ListPreference
android:key="mycities"
android:title="所属城市"
android:summary="点击弹出城市列表"
android:dialogTitle="请选择城市"
android:entries="@array/cities"
android:entryValues="@array/cities"/>
</PreferenceCategory> </PreferenceScreen>
上方代码中,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文件中定义这个被引用的城市列表(即数据来源):
<?xml version="1.0" encoding="utf-8"?>
<resources> <string name="app_name">m05_PrefFragment01</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string> <string-array name="cities">
<item>成都</item>
<item>重庆</item>
<item>黄冈</item>
</string-array> </resources>
上方代码中,8至12行:即加粗部分,是我添加的数据源。
运行程序效果如下:


六、监听事件onPreferenceTreeClick()方法:
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen Preference preference)
当任何一个preference控件被点击,都将触发该方法。但是可以通过preference.getKey()这个方法找到具体是哪个preference被点击了,因为每个preference的key都是唯一的。
【实例】
现将preferences.xml这个设置选项的布局文件,定义如下:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <!-- 设置的类别 -->
<PreferenceCategory
android:key="mylocation"
android:summary="我的位置"
android:title="我的位置源" >
<CheckBoxPreference
android:key="wireless_network"
android:summary="使用无线网络查看应用程序(例如Google地图)中的位置"
android:title="使用无线网络" />
<CheckBoxPreference
android:key="gps_satellite_setting"
android:summary="定位时,精确到街道级别(取消选择可节约电量)"
android:title="启用GPS卫星设置" />
</PreferenceCategory> <PreferenceCategory
android:key="mymessage"
android:summary="个人信息设置"
android:title="个人信息设置" >
<CheckBoxPreference
android:key="yesno_save_individual_info"
android:title="是否保存个人信息" />
<EditTextPreference
android:key="individual_name"
android:summary="请输入真实姓名"
android:title="姓名 " />
<ListPreference
android:entries="@array/cities"
android:entryValues="@array/cities"
android:key="mycity"
android:summary="所属城市"
android:title="所属城市" />
</PreferenceCategory> </PreferenceScreen>
运行效果如下:

现在我们需要做的是,选中上方红框中的CheckBoxPreference,对应下面的EditTextPreference为编辑状态;否则,如果CheckBoxPreference没有被选中,则EditTextPreference为不可编辑状态。修改PrefFragment.java的代码,其完整版代码如下:
package com.example.m05_preffragment01; import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen; public class PrefFragment extends PreferenceFragment { @Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState); //从xml文件加载选项
addPreferencesFromResource(R.xml.preferences);
} @Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) {
//如果“保存个人信息”这个按钮被选中,将进行括号里面的操作
if("yesno_save_individual_info".equals(preference.getKey())) {
CheckBoxPreference checkBoxPreference = (CheckBoxPreference)findPreference("yesno_save_individual_info");
EditTextPreference editTextPreference = (EditTextPreference)findPreference("individual_name");
//让editTextPreference和checkBoxPreference的状态保持一致
editTextPreference.setEnabled(checkBoxPreference.isChecked());
}
// TODO Auto-generated method stub
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
}
代码解释:
当任何一个preference控件被点击,都将触发onPreferenceTreeClick()方法(22行),但是可以通过preference.getKey()这个方法找到具体是哪个preference被点击(25行)。
26行、27行:通过public Preference findPreference(CharSequence key)找到对应的preference,然后强转为它的子类。
29行:核心代码,让editTextPreference和checkBoxPreference的状态保持一致。
运行效果如下:


这样,我们的功能就实现了。
Android数据存储(二)----PreferenceFragment详解的更多相关文章
- Android Telephony分析(二) ---- RegistrantList详解
前言 本文主要讲解RegistrantList的原理,以及如何快速分析RegistrantList相关的代码流程.在Telephony模块中,在RIL.Tracker(ServiceStateTrac ...
- Android开发数据存储之ContentProvider详解
转载:十二.ContentProvider和Uri详解 一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据,也就是说你可 ...
- IOS 数据存储之 FMDB 详解
FMDB是用于进行数据存储的第三方的框架,它与SQLite与Core Data相比较,存在很多优势. FMDB是面向对象的,它以OC的方式封装了SQLite的C语言API,使用起来更加的方便,不需要过 ...
- IOS 数据存储之 SQLite详解
在IOS开发中经常会需要存储数据,对于比较少量的数据可以采取文件的形式存储,比如使用plist文件.归档等,但是对于大量的数据,就需要使用数据库,在IOS开发中数据库存储可以直接通过SQL访问数据库, ...
- Android 开发 存储目录的详解
简介 Android设备,有3个地方的文件存储位置,他们分别是: 内部存储空间(用户无法浏览到此目录) 外部存储空间(就是手机自身的文件管理目录,用户可以浏览) SD卡的存储空间(需要插入T卡) Sh ...
- Android 数据加密算法 Des,Base64详解
一,DES加密: 首先网上搜索了一个DES加密算法工具类: import java.security.*;import javax.crypto.*; public class DesHelper { ...
- Android Telephony分析(三) ---- RILJ详解
前言 本文主要讲解RILJ工作原理,以便更好地分析代码,分析业务的流程.这里说的RILJ指的是RIL.java (frameworks\opt\telephony\src\java\com\andro ...
- Android数据存储之GreenDao 3.0 详解
前言: 今天一大早收到GreenDao 3.0 正式发布的消息,自从2014年接触GreenDao至今,项目中一直使用GreenDao框架处理数据库操作,本人使用数据库路线 Sqlite----> ...
- 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高
第十一章 搭建云端服务器 该章主要介绍了移动后端服务的概念以及Bmob的使用,比较简单,所以略过不总结. 第十三章 Android实例提高 该章主要介绍了拼图游戏和2048的小项目实例,主要是代码,所 ...
- Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能
Android高效率编码-第三方SDK详解系列(二)--Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能 我的本意是第二篇写Mob的shareSD ...
随机推荐
- IT外包行业与职业发展
在IT行业,总是有一些IT外包公司的存在,凡是存在的都是合理的.当你做为IT从业人员应该尽量避免去外包公司工作 .特别是你从事软件开发工作. 先来说说缘由,一些外包公司本来是从事软 ...
- DWR的Reverse Ajax技术实现
DWR的逆向ajax其实主要包括两种模式:主动模式和被动模式.其中主动模式包括Polling和Comet两种,被动模式只有Piggyback这一种. 所谓的Piggyback指的是如果后台有什么内容需 ...
- jquery 下拉选择框/复选框常用操作
通常 1.我们需要获取select中选中的值,可以使用: $("#selectID").find("option:selected").val(); --一般 ...
- stl空间配置器线程安全问题补充
摘要 在上一篇博客<STL空间配置器那点事>简单介绍了空间配置器的基本实现 两级空间配置器处理,一级相关细节问题,同时简单描述了STL各组件之间的关系以及设计到的设计模式等. 在最后,又关 ...
- [Azure] Notification Hubs注册模式
[Azure] Notification Hubs注册模式 关于Azure Notification Hubs的注册模式,可以参考下列连结的文件内容. Notification Hubs Featur ...
- Exchange 2013 、Lync 2013、SharePoint 2013
Office办公系列 在企业中广泛应用,目前服务的客户当中,部分客户已经应用到了 Exchange.Lync.CRM.SharePoint等产品,在开发当中多多少少会涉及到集成,为了更好的服务客户.了 ...
- HTML5离线缓存Manifest
web app不比PC,有性能和流量方面的考虑,离线应用越来越重要,虽然浏览器有缓存机制,但是时常不靠谱,更何况普通情况下html文件是没法缓存的,断网之后一切over. 什么是manifest? 简 ...
- XStream的例子
写个小例子,方便以后复习: 1 package com.demo; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 impor ...
- Office 365 - SharePoint 2013 Online 之母版页和页面布局
1.打开https://login.microsoftonline.com,登陆,点击SharePoint,如下图: 2.打开网站集,可以查看.添加.删除等管理操作: 3.打开一个站点,如下图: 4. ...
- SharePoint 2013 JQuery Asset Picket
var b = new AssetPickerConfig(""); b.ClientID = ""; b.DefaultAssetLocation = & ...