PreferenceFragment详解

article/2025/11/6 3:29:56

在上篇文章中我们讲述了Android 5.1 Settings的源码解析Android 5.1 Settings模块源码分析_Flying snow-CSDN博客,

其中在介绍到Android的Sub Setting时,我们说到基本上都是使用的PreferenceFragment技术,今天我们就来了解一下关于PreferenceFragment相关的技术吧。

PreferenceFragment简述:

当我们在开发Android项目时一般都会用到首选项设置,在Android3.0之前我们都使用PreferenceActivity类来进行操作,这些设置习惯会被Preference自动保存下来,以便下次进入后恢复上一次的选择状态。

PreferenceActivity和普通的Activity不同,他们不使用setContentView加载布局,而是加载选项设置布局,而选择设置布局是以PreferenceScreen作为根元素的xml布局文件。

但在Android3.0之后Google不推荐我们使用PreferenceActivity来进行首选项设置,而是替换成了PreferenceFragment,其实二者的用法类似,只不过PreferenceFragment更容易扩展,所以推荐使用PreferenceFragment进行首选项设置。

PreferenceFragment是直接继承自Fragment,另选项布局xml文件的根节点一定是<PreferenceScreen>,在这个元素中我们可以添加不同的Preference,常用的Preference控件如下:

CheckBoxPreference、SwitchPreference、EditTextPreference、ListPreference、MultiSelectListPreference、

PreferenceCategory等。

接下来我们将通过分析一个Demo来了解PreferenceFragment吧。

首先来看应用的主界面:

以上为本次Demo的主界面,接下来将对每个选项的代码进行分析。

先建一个PrefFragment类继承自PreferenceFragment然后加载首选项配置的xml文件preferences.xml

public class PrefFragment extends PreferenceFragment {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);addPreferencesFromResource(R.xml.preferences);}
//重写的以下方法请看后面讲解@Overridepublic boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {if ("select_linkage".equals(preference.getKey())) {CheckBoxPreference checkBox = (CheckBoxPreference) findPreference("select_linkage");ListPreference editBox = (ListPreference) findPreference("select_city");editBox.setEnabled(checkBox.isChecked());}return super.onPreferenceTreeClick(preferenceScreen, preference);}}


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

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);getFragmentManager().beginTransaction().replace(android.R.id.content, new PrefFragment()).commit();}
}

接下来将对preferences.xml文件进行分析,并使用效果图进行展示,先附上完整的xml代码:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"android:title="Settings" ><!-- 单独一个复选框 --><PreferenceCategory android:title="我是CheckBox" ><CheckBoxPreferenceandroid:key="checkbox_preference"android:summary="是否勾选复选框"android:title="我是复选框" /></PreferenceCategory><!-- 单独一个Switch开关 --><PreferenceCategory android:title="我是Switch" ><SwitchPreferenceandroid:key="switch_preference"android:summary="是否打开我呢?"android:summaryOff="关闭"android:summaryOn="打开"android:switchTextOff="开关被关闭了"android:switchTextOn="开关被打开了"android:title="开关" /></PreferenceCategory><!-- 很多选项的综合 --><PreferenceCategory android:title="大综合" ><EditTextPreferenceandroid:dialogTitle="请输入你的名字"android:key="edittext_preference"android:summary="这是一个编辑框"android:title="我是编辑框" /><ListPreferenceandroid:dialogTitle="请选择一项"android:entries="@array/cities"android:entryValues="@array/cities"android:key="single_list_preference"android:summary="这是一个单选列表"android:title="我是单选框" /><MultiSelectListPreferenceandroid:dialogTitle="请选择一项"android:entries="@array/cities"android:entryValues="@array/cities"android:key="multi_list_preference"android:summary="这是一个多选列表"android:title="我是多选框" /><RingtonePreferenceandroid:key="ringtone_preference"android:ringtoneType="all"android:showSilent="true"android:summary="选择各种手机铃声"android:title="铃声" /><PreferenceScreenandroid:summary="是否能打开页面"android:title="打开页面" ><intentandroid:action="android.intent.action.VIEW"android:data="http://www.baidu.com" /></PreferenceScreen></PreferenceCategory><!-- 启动新的页面 --><PreferenceCategory android:title="启动新页面设置" ><PreferenceScreenandroid:summary="点我到达新的页面"android:title="新开页面展示" ><CheckBoxPreferenceandroid:defaultValue="true"android:key="select_me"android:summaryOff="对不起,你没有勾选我"android:summaryOn="是的,你勾选了我"android:title="是否勾选了我?" /><CheckBoxPreferenceandroid:defaultValue="false"android:key="like_android"android:summaryOff="不不,我没太大兴趣"android:summaryOn="是的,我特别喜欢"android:title="是否喜欢Android呢?" /></PreferenceScreen></PreferenceCategory><!-- 调试onPreferenceTreeClick接口 --><PreferenceCategory android:title="联动设置" ><CheckBoxPreferenceandroid:key="select_linkage"android:title="是否选择联动" /><ListPreferenceandroid:dialogTitle="请选择一个城市"android:entries="@array/cities"android:entryValues="@array/cities"android:key="select_city"android:summary="我是否能选择看联动设置"android:title="是否能选择" /></PreferenceCategory></PreferenceScreen>


(1)首次分析CheckBoxPreference和SwitchPreference的功能:

<!-- 单独一个复选框 --><PreferenceCategory android:title="我是CheckBox" ><CheckBoxPreferenceandroid:key="checkbox_preference"android:summary="是否勾选复选框"android:title="我是复选框" /></PreferenceCategory><!-- 单独一个Switch开关 --><PreferenceCategory android:title="我是Switch" ><SwitchPreferenceandroid:key="switch_preference"android:summary="是否打开我呢?"android:summaryOff="关闭"android:summaryOn="打开"android:switchTextOff="开关被关闭了"android:switchTextOn="开关被打开了"android:title="开关" /></PreferenceCategory>


<PreferenceCategory>是一个大类别,里面用来存放任意的Preference控件,在上面的代码中<PreferenceCategory>类别中各放入一个CheckBox和SwitchPreference控件,运行效果如下:

运行后,会在/data/data/<packagename>/shared_prefs/目录下生成对应的xml文件,用于存储设置的结果状态,

另可通getPreferenceManager().setSharedPreferenceName()方法来设置文件的名称。

所有的控件都需要合入android:key属性,不然无法保存结果状态,android:title是大标题,android:summary是小标题。

(2)我们接着往下分析:

<!-- 很多选项的综合 --><PreferenceCategory android:title="大综合" ><EditTextPreferenceandroid:dialogTitle="请输入你的名字"android:key="edittext_preference"android:summary="这是一个编辑框"android:title="我是编辑框" /><ListPreferenceandroid:dialogTitle="请选择一项"android:entries="@array/cities"android:entryValues="@array/cities"android:key="single_list_preference"android:summary="这是一个单选列表"android:title="我是单选框" /><MultiSelectListPreferenceandroid:dialogTitle="请选择一项"android:entries="@array/cities"android:entryValues="@array/cities"android:key="multi_list_preference"android:summary="这是一个多选列表"android:title="我是多选框" /><RingtonePreferenceandroid:key="ringtone_preference"android:ringtoneType="all"android:showSilent="true"android:summary="选择各种手机铃声"android:title="铃声" /><PreferenceScreenandroid:summary="是否能打开页面"android:title="打开页面" ><intentandroid:action="android.intent.action.VIEW"android:data="http://www.baidu.com" /></PreferenceScreen></PreferenceCategory>

这段代码中包含很多控件,其中EditTextPreference是文本框选项,可以用来手动输入文字,android:dialogTitle属性用来设置对话框的标题内容,点击的效果图如下:

然后ListPreference是单选的列表选项,其中android:entries和android:entryValues需要指定数组作为值,

二者的区别在于android:entries中的值是供用户查看和选择的(即展示在界面上),

而android:entryValues的值是真正存储到手机中的值,我们在看下引入为entries和entryValues的值的cities数组。

<?xml version="1.0" encoding="utf-8"?>
<resources><string-array name="cities"><item >南京</item><item >北京</item><item >上海</item><item >杭州</item><item >合肥</item></string-array>
</resources>

最后的运行效果图如下:

接下来分析MultiSelectListPreference控件,这是一个多选的列表选项,和单选的唯一区别就是可以进行多项选择,

效果图如下:

最后我们分析一下RingtonePreference和<PreferenceScreen>中的Intent,RingtonePreference是一个铃声选项,

可以加载手机中的铃声和短音,并做相应的处理。

<PreferenceScreen>中的Intent加载链接、拨打电话、发送短信等等,只要有对应的Intent的,都可以进行操作。

(3)我们在接着往下分析:

<!-- 启动新的页面 --><PreferenceCategory android:title="启动新页面设置" ><PreferenceScreenandroid:summary="点我到达新的页面"android:title="新开页面展示" ><CheckBoxPreferenceandroid:defaultValue="true"android:key="select_me"android:summaryOff="对不起,你没有勾选我"android:summaryOn="是的,你勾选了我"android:title="是否勾选了我?" /><CheckBoxPreferenceandroid:defaultValue="false"android:key="like_android"android:summaryOff="不不,我没太大兴趣"android:summaryOn="是的,我特别喜欢"android:title="是否喜欢Android呢?" /></PreferenceScreen></PreferenceCategory>

<PreferenceCategory>中包含一个<PreferenceScreen>,通过这样的关系可以打开一个新的页面,

并且里面同时包含两个CheckBoxPreference控件,其中android:defaultValue是设置默认是否选择,

效果图如下:

这是一个新开的页面,里面只包含两个CheckBoxPreference控件,并且通过android:summaryOn

和android:summaryOff属性控制选择与否的差别。

(4)最后着重分析一下onPreferenceTreeClick()监听事件:

<!-- 调试onPreferenceTreeClick接口 --><PreferenceCategory android:title="联动设置" ><CheckBoxPreferenceandroid:key="select_linkage"android:title="是否选择联动" /><ListPreferenceandroid:dialogTitle="请选择一个城市"android:entries="@array/cities"android:entryValues="@array/cities"android:key="select_city"android:summary="我是否能选择看联动设置"android:title="是否能选择" /></PreferenceCategory>

运行的效果图如下:


 

当选中是否联动的CheckBoxPreference时,下面的ListPreference可使用,但当不选择CheckBoxPreference时,ListPreference将变成灰色无法被选中。

控制这段逻辑的代码在之前提到的Fragment中就已体现,这里单独拉出来分析一下:

@Overridepublic boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {if ("select_linkage".equals(preference.getKey())) {CheckBoxPreference checkBox = (CheckBoxPreference) findPreference("select_linkage");ListPreference editBox = (ListPreference) findPreference("select_city");editBox.setEnabled(checkBox.isChecked());}return super.onPreferenceTreeClick(preferenceScreen, preference);}

当任意的Preference控件被点击时,都会触发onPreferenceTreeClick这个方法回调,且通过preference.getKey()这个方法可以定位到哪个控件进行了操作,最终通过editBox.setEnabled(checkBox.isChecked());将CheckBox和ListPreference进行了绑定。

到这里PreferenceFragment的分析也就告一段落了,经过之前的分析大家也应该了解到这个类的优点在哪里,平时我们在做自己的项目时,遇到类似于这样的设置属性时,无需一个一个控件去慢慢布局了,而且那样处理逻辑时比这种方式复杂太多了。所以以后遇到类似的问题还是使用这种方式处理更加方便。


http://chatgpt.dhexx.cn/article/0HwwW3mM.shtml

相关文章

Android进阶——Preference详解之Preference系的基本应用和管理(二)

引言 前面一篇文章Android进阶——Preference详解之初识Preference及Preference系&#xff08;一&#xff09;简单描述下了Preference的家族构成和基本知识&#xff0c;相信对于Preference早已不会陌生&#xff0c;肯定也跃跃欲试了吧&#xff0c;这篇文章就给大家总结下Prefe…

Android自定义PreferenceScreen的Layout布局,并获取控件

先说一下需求&#xff0c;要在<PreferenceScreen>里添加一个自定义的Layout&#xff0c;实现如下效果&#xff1a; 操作步骤&#xff1a; 1、在res/layout目录创建一个xml文件&#xff0c;名为my_preference_layout.xml&#xff0c;代码如下&#xff1a; <?xml ver…

PreferenceScreen的使用(非常有用)

在res下建个xml文件夹,建立2个xml文件: preferencescreentest_one.xml <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"android:key="using_categor…

使用PreferenceActivity和PreferenceScreen构建应用的设置

对于每个应用程序来说&#xff0c;都要有一些属于用户自己的设置&#xff0c;满足不同需求。当我们点击menu时&#xff0c;如下&#xff1a; 点击settings时&#xff0c;出现&#xff1a; 那么这样的效果是怎么实现的呢&#xff1f;我只是来个简单介绍&#xff0c;给自己做备忘…

PreferenceScreen

对于每个应用程序来说&#xff0c;都要有一些属于用户自己的设置&#xff0c;满足不同需求。当我们点击menu时&#xff0c;如下&#xff1a; 点击settings时&#xff0c;出现&#xff1a; 那么这样的效果是怎么实现的呢&#xff1f;我只是来个简单介绍&#xff0c;给自己做备忘…

PreferenceFragment的使用

文章目录 PreferenceFragment简介PreferenceFragment使用PreferenceFragment 扩展 PreferenceFragment简介 在我们写一个项目的时候&#xff0c;基本都有选项设置界面&#xff0c;这类设置界面的原理基本都是本地的一些个性化设置&#xff0c;通过读取本地设置来改变某些差异显…

Android中Preference的使用以及监听事件分析

转载请注明出处: http://blog.csdn.net/qinjuning 在Android系统源码中&#xff0c;绝大多数应用程序的UI布局采用了Preference的布局结构&#xff0c;而不是我们平时在模拟器中构建应用程序时使用的View布局结构&#xff0c;例如&#xff0c;Setting模块中布局。当然&#xf…

screentogif 录屏

screentogif的由来 screentogif于2013年诞生&#xff0c;主要的开发者是巴西帅哥Nicke Manarin。 最初的目的只是为了学习和提供一款软件供开发者个人使用。 在2016重新启动项目&#xff0c;使得screentogif变得更加实用。 screentogif的安装 进入官网下载软件安装包。 s…

android PreferenceScreen使用笔记

preference.xml <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"><Preference android:title="基本信息"android:layout="@layout/tex…

PreferenceScreen 的使用

java代码&#xff1a; public class Main3Activity extends PreferenceActivity {Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); // setContentView(R.layout.activity_main3); //加载布局文件&#xff0c;相当于…

PreferenceScreen的应用

PreferenceScreen preference是偏好&#xff0c;首选的意思&#xff0c;PreferenceScreen个人翻译成 “偏好显示”&#xff0c;明白这个意思就好&#xff0c;就是说根据特点灵活的定义显示内容风格&#xff0c;一个屏幕可以包含多个风格&#xff0c;像系统自带的声音设置界面。…

PreferenceScreen 中如何自定义SwitchPreferenceCompat的布局

PreferenceScreen 中如何自定义SwitchPreferenceCompat的布局 Android Preference 使用请看这篇 Android Preference使用 系统设置的代码&#xff1a; public class SetActivity extends AppCompatActivity { Override protected void onCreate(Bundle savedInstanceSta…

Preference的使用(2) --- PreferenceCategory PreferenceScreen

上一节有讲到Preference的基本使用跟API的介绍 &#xff0c;没有看的话请先阅读 Preference的使用&#xff08;1&#xff09; 现在介绍其子类PreferenceCategory 跟 PreferenceScreen&#xff0c;现在看下继承关系 如上图&#xff0c;他们都是继承自PreferenceGroup的先看一…

preferenceActivity和preferencescreen用法

1. 首先生成一个preferencescreen的xml文件..看代码: <?xml version"1.0" encoding"utf-8"?><PreferenceScreen xmlns:android"http://schemas.android.com/apk/res/android"> <CheckBoxPreference android:key"chec…

Android Settings中Preference的理解以及使用

Preference 是Android App 中重要的控件之一&#xff0c;Settings 模块大部分都是通过 Preference 实现 优点&#xff1a; Preference 可以自动显示我们上次设置的数据&#xff0c;Android提供preference这个键值对的方式来处理这种情况&#xff0c;自动保存这些数据&#xff…

使用 Android PreferenceScreen 偏好显示类(android.preference.PreferenceScreen)

http://edu.gamfe.com/tutor/d/36925.html PreferenceScreen preference是偏好&#xff0c;首选的意思&#xff0c;PreferenceScreen个人翻译成 “偏好显示”&#xff0c;明白这个意思就好&#xff0c;就是说根据特点灵活的定义显示内容风格&#xff0c;一个屏幕可以包含多个风…

android开发之PreferenceScreen使用详解

一 PreferenceActivity 1、PreferenceActivity概述 PreferenceActivity是一个抽象类&#xff0c;继承于ListActivity&#xff0c;以列表形式视图来展现界面,加载的整个View也是基于ListActivity中那个ListView的&#xff0c;其最主要的优势在于添加Preference后可让其状态持久化…

Android PreferenceScreen的使用和详解(设置页面)

PreferenceScreen是设置选项的配置文件&#xff0c;一般用在设置页面&#xff0c;用来当前的状态是保存在。该状态无须用户处理&#xff0c;存在SharedPreferences中。 1.如何使用 1.1布局文件的创建 PreferenceScreen的用法和layout的类似&#xff0c;都是通过xml文件来管理…

Semaphore - 信号量的简单介绍与使用

一、Semaphore使用 // Test_Semaphore.cpp : 定义控制台应用程序的入口点。 //#include "stdafx.h" #include <windows.h> #include <iostream> #include <time.h>using namespace std;const int g_num 3; HANDLE g_semp[g_num] { NULL }; HAND…

C++中多线程管理

1&#xff0c;函数1 CreateSemaphore 创建或打开一个信号量&#xff0c;信号可以理解为停车场&#xff0c;创建和增加信号&#xff0c;可以理解为创建一个停车场&#xff0c;和可以停放的汽车&#xff0c; 如下&#xff1a; CreateSemaphore(NULL, 2, 3, szSemaphoreA);//开…