博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android数据存储(二)----PreferenceFragment详解
阅读量:5249 次
发布时间:2019-06-14

本文共 7307 字,大约阅读时间需要 24 分钟。

【声明】 

欢迎转载,但请保留文章原始出处→_→ 

生命壹号:

文章来源:

 

【正文】

一、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行)

1 package com.example.m05_preffragment01; 2  3 import android.os.Bundle; 4 import android.preference.PreferenceFragment; 5  6 public class PrefFragment extends PreferenceFragment { 7     @Override 8     public void onCreate(Bundle savedInstanceState) { 9         // TODO Auto-generated method stub10         super.onCreate(savedInstanceState);11         12         //从xml文件加载选项 13         addPreferencesFromResource(R.xml.preferences);14     }15 }

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

1 package com.example.m05_preffragment01; 2  3 import android.app.Activity; 4 import android.app.FragmentManager; 5 import android.app.FragmentTransaction; 6 import android.os.Bundle; 7  8 public class MainActivity extends Activity { 9 10     @Override11     protected void onCreate(Bundle savedInstanceState) {12         super.onCreate(savedInstanceState);13         setContentView(R.layout.activity_main);14         15         //加载PrefFragment16         FragmentManager fragmentManager = getFragmentManager();17         FragmentTransaction transaction = fragmentManager.beginTransaction();18         PrefFragment prefFragment = new PrefFragment();19         transaction.add(R.id.prefFragment, prefFragment);20         transaction.commit();21         22     }23     24 }

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

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

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

 

五、preference详解:

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

preferences.xml举例如下:

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

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

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

getPreferenceManager().setSharedPreferencesName("mysetting");

文本内容如下:

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

文本内容显示如下:

 

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

1 
2
4 5
9
14 15
20 21
22 23
27
32 33
38 39
40 41

运行效果如下:

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

 

3、ListPreference控件:

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

上方代码中,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:entriesandroid: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文件中定义这个被引用的城市列表(即数据来源):

1 
2
3 4
m05_PrefFragment01
5
Settings
6
Hello world!
7 8
9
成都
10
重庆
11
黄冈
12
13 14

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

运行程序效果如下:

 

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

public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen Preference preference) 

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

【实例】

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

运行效果如下:

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

1 package com.example.m05_preffragment01; 2  3 import android.os.Bundle; 4 import android.preference.CheckBoxPreference; 5 import android.preference.EditTextPreference; 6 import android.preference.Preference; 7 import android.preference.PreferenceFragment; 8 import android.preference.PreferenceScreen; 9 10 public class PrefFragment extends PreferenceFragment {11 12     @Override13     public void onCreate(Bundle savedInstanceState) {14         // TODO Auto-generated method stub15         super.onCreate(savedInstanceState);16         17         //从xml文件加载选项 18         addPreferencesFromResource(R.xml.preferences);19     }20     21     @Override22     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,23             Preference preference) {24         //如果“保存个人信息”这个按钮被选中,将进行括号里面的操作25         if("yesno_save_individual_info".equals(preference.getKey())) {            26             CheckBoxPreference checkBoxPreference = (CheckBoxPreference)findPreference("yesno_save_individual_info");27             EditTextPreference editTextPreference = (EditTextPreference)findPreference("individual_name");28             //让editTextPreference和checkBoxPreference的状态保持一致29             editTextPreference.setEnabled(checkBoxPreference.isChecked());30         }31         // TODO Auto-generated method stub32         return super.onPreferenceTreeClick(preferenceScreen, preference);33     }34 }

代码解释:

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

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

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

运行效果如下:

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

转载于:https://www.cnblogs.com/qianguyihao/p/4020469.html

你可能感兴趣的文章
ASP.NET使网页弹出窗口不再困难
查看>>
Leetcode Balanced Binary Tree
查看>>
Leetcode 92. Reverse Linked List II
查看>>
windown快速安装xgboost
查看>>
Linux上安装Libssh2
查看>>
九.python面向对象(双下方法内置方法)
查看>>
go:channel(未完)
查看>>
[JS]递归对象或数组
查看>>
LeetCode(17) - Letter Combinations of a Phone Number
查看>>
Linux查找命令对比(find、locate、whereis、which、type、grep)
查看>>
路由器外接硬盘做nas可行吗?
查看>>
python:从迭代器,到生成器,再到协程的示例代码
查看>>
Java多线程系列——原子类的实现(CAS算法)
查看>>
在Ubuntu下配置Apache多域名服务器
查看>>
多线程《三》进程与线程的区别
查看>>
linux sed命令
查看>>
html标签的嵌套规则
查看>>
[Source] Machine Learning Gathering/Surveys
查看>>
HTML <select> 标签
查看>>
类加载机制
查看>>