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

article/2025/11/6 3:21:55

引言

前面一篇文章Android进阶——Preference详解之初识Preference及Preference系(一)简单描述下了Preference的家族构成和基本知识,相信对于Preference早已不会陌生,肯定也跃跃欲试了吧,这篇文章就给大家总结下Preference、PreferenceActivity、PreferenceGroup、RingtonePreference的普通应用和管理,还有通过一些测试来验证一些机制和原理。

一、PreferenceActivity

1、PreferenceActivity概述

PreferenceActivity是一个抽象类,继承于ListActivity,以列表形式视图来展现界面,加载的整个View也是基于ListActivity中那个ListView的,其最主要的优势在于添加Preference后可让其状态持久化储存(通过SharedPreferences,一般存储在/data/data//shared_prefs文件夹下的默认名为“app package name”+”_preferences.xml”的文件里),比如说用户勾选CheckBox后退出应用,下一次进入到这一界面时候,对应的是CheckBox依然是被勾选状态,如果要实现这样的机制,我们自己也可以实现,但是没有必要,因为Android已经替我们实现了,就是我们的这一系列的主角——Preference,Preference会自动地替我们去保存这些状态对应的值到对应的SharedPreferences文件里,而当我们每次启动的时候Acitivity(PreferenceActivity)会自动根据key去获取相关数据,完成用户界面的更新。我们手机当中的系统设置就是及其典型的Preference的应用,也正是由于工作中需要去客制化Settings,才有了这一系列的文章。
这里写图片描述
上图是我们定制的Settings模块中的对应的部分SharedPreferences。关于Preference对应的SharedPreferences往往很容易被我们忽视两点

  • 并非我们第一次打开相应界面之后就会自动创建对应的SharedPreferences文件,而是在我们改变了原有状态时候

  • 并非所有的Preference及其子类都会创建,仅仅针对需要记录状态的Preference

2、PreferenceActivity的初始化

PreferenceActivity其实和普通的Activity本质上来说区别不大,只不过多了些自动去读取SharedPrefrences的值来更新界面和其他一些逻辑,所以初始化本质上来说并无很大的区别,但是与普通Activity的layout不同,PreferenceActivity的layout我们可以理解成为两个部分:其他View和一个id为android.R.id.list的ListView,那么我们可以理解成为当我们在onCreate方法里先调用setContentView完成整个Activity的View的构建layout文件里必须包含id为android.R.id.list的listView,否则会报E/AndroidRuntime: Caused by: java.lang.RuntimeException: Your content must have a ListView whose id attribute is ‘android.R.id.list’),再调用addPreferencesFromResource来完成Preference界面的构建;当然也可以只调用addPreferencesFromResource方法。

1、继承PreferenceActivity实现具体业务类,重写相关生命周期方法

public class MainActivity extends PreferenceActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);addPreferencesFromResource(R.xml.demo_preference);}...}

2、通过addPreferencesFromResource(xml资源id)加载静态xml资源文件 或者 完全通过代码构造对象再动态添加

res文件夹下新建xml文件夹,再在xml文件中新建对应的xml资源,xml资源类似我们在使用普通Activity时的layout文件,PreferenceActivity独特之处在于并不是使用普通的layout文件,而是使用res下xml文件夹下的xml资源文件

res/xml/demo_preference.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" ><CheckBoxPreference
        android:key="key_checkbox_preference"android:summary="Some summay for CheckBoxPreference"android:title="The Title Of CheckBoxPreference" />
</PreferenceScreen>

也可通过代码去构造对象,添加容器之后再调用setPreferenceScreen(PreferenceScreen preferenceScreen)把容器对象设置到Activity上

private void createPreference(){PreferenceScreen preferenceScreen = this.getPreferenceManager().createPreferenceScreen(this);//先构建PreferenceScreen对象得到一个布局容器this.setPreferenceScreen(preferenceScreen);//设置容器CheckBoxPreference checkBoxPreference=new CheckBoxPreference(this);//构建一个子Preference,待添加到容器中checkBoxPreference.setKey(CHECKBOXPRERENCE_KEY);//设置keycheckBoxPreference.setTitle("The Title Of CheckBoxPreference");//设置titlecheckBoxPreference.setSummary("Some summay for CheckBoxPreference");preferenceScreen.addPreference(checkBoxPreference);//添加到容器中}

二、Preference的使用

前一篇文章我们讲述了Preference家族的基类(接下来我们所要介绍的其他子类Preference一定是继承了他的所有属性也可以理解成都是在继承他所展示的UI效果及交互功能的基础上升级的)而且Preference可以实例化,那么我们就可以把他看成对应的一个组件,其实和我们熟悉的TextView一样,所以我们需要使用的时候第一步肯定是先得到他的对象——而构造对象我们都可以通过两种方式:通过其对应的构造方法或者其他方法通过xml映射(或许说法不够准确),接着第二步PreferenceActivity的初始化,再接着根据业务设置相关监听。

1、构造Preference容器和Preference对象

前面Android进阶——Preference详解之初识Preference及Preference系(一)已经讲过PreferenceScreen只能作为top-level节点,而构造对象我们都可以通过两种方式:通过其对应的构造方法或者其他方法通过映射xml(或者讲法不够准确)

res/xml/test_preference.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"android:key="using_categories_in_root_screen"android:summary="Using Preference Categories"android:title="Categories"><Preference
        android:key="key_prerence"android:title="Preferece"android:summary="Preference Demo"/>
</PreferenceScreen>

2、初始化PreferenceActivity和设置相关监听

常见的Preference的事件有两个:setOnPreferenceClickListeneronPreferenceChange

  • 设置Preference点击监听
 preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {@Overridepublic boolean onPreferenceClick(Preference preference) {//当接收到Click事件之后触发return true;}});
  • 设置Preference对应的SharedPrefernces值监听
preference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {@Overridepublic boolean onPreferenceChange(Preference preference, Object newValue) {//如果值改变了我们可以通过监听这个事件来处理return true;}});
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//activity_main里必须存在id为android.R.id.list的ListView否则报E/AndroidRuntime:  Caused by: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'addPreferencesFromResource(R.xml.test_preference);mContext=getApplicationContext();preference=findPreference(PREFERENCE_KEY);preference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {@Overridepublic boolean onPreferenceChange(Preference preference, Object newValue) {//如果值改变了我们可以通过监听这个事件来获取新值Toast.makeText(mContext, String.format("Preference的值为%s", newValue),Toast.LENGTH_LONG).show();return true;}});//设置Preference的点击事件监听preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {@Overridepublic boolean onPreferenceClick(Preference preference) {//当接收到Click事件之后触发Toast.makeText(mContext, "Preference Clicked",Toast.LENGTH_LONG).show();return true;}});}

这里写图片描述

3、Preference的常用xml属性

xml属性说明
android:iconPreference的icon
android:summary副标题、说明(小字体显示)
android:title标题
android:key对应的SharedPrefrences的key值
android:layoutPreferenceActivity的布局文件即如果设置了这个属性则会覆盖原来的UI
android:fragment应用在PreferenceActivity中时,当用户点击这个Preference时,启动一个新的Fragment
android:enabled设置Preference是否可用,false阴影状态不可操作
android:orderPreference的排序,整数类型如”100”
android:persistenttrue时,系统会帮助我们去保存该设置,即使重启后依然能记忆之前的设置,这也是所谓的持久化 。这里 将 android:persistent设置为False,表明不需要让系统去做持久化,开发者系统通过自己的方式去实现持久化。
android:selectablePreference是否可选,false可以点击但无响应
android:shouldDisableView当View disabled的时候是否Preference也一样Disabled.
android:widgetLayout自定义Preference用到给子Preference定义布局。
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"android:title="PreferenceScreen">
<PreferenceCategory
    android:key="key_prerence"android:summary="Preference Categories Summary"android:title="Preference Categories"><CheckBoxPreference
        android:icon="@mipmap/ic_launcher"android:key="key_chkpreference"android:title="CheckBoxPreferenceCheckBoxPreferenceCheckBoxPreferenceCheckBoxPreference"android:summary="CheckboxPreference summary"/><Preference
        android:title="Preference"android:key="key_pre"android:icon="@mipmap/ic_red_launcher"android:layout="@layout/activity_main"/><EditTextPreference
        android:icon="@mipmap/ic_blue_launcher"android:key="key_edtkpreference"android:title="EditPreference"android:summary="EditPreference summary"/>
</PreferenceCategory>
</PreferenceScreen>

这里写图片描述

4、Preference的xml文件中的常用标签intentextra

在xml文件的Preference标签中,我们可以添加intent来为我们快速实现一种意图,比如说快速打开一个网页,或者快速启动一个Activity等等,还可以使用extraintent标签加参数来传递参数(再通过getIntent().getStringExtra(“key”)来获取)。

点击这个Preference则会自动去调用浏览器打开http://www.hao123.com网页

    <Preference
        android:title="Click me open the web"android:key="key_pref_intent"><intent android:action="android.intent.action.VIEW"android:data="http://www.hao123.com"/><!--可以通过<extra>传附加信息getIntent().getStringExtra("reused_key") --><extra
            android:name="key"android:value="value"/></Preference>

启动指定类

 <Preference
        android:title="PREFERENCE TITLE"><!-- android:targetPackage是应用程序的包名,而android:targetClass的路径在子包下的类 --><!-- android:targetPackage设置为子包,运行时则找不到Activity --><intent
            android:action="ACTION_A_INTENT"android:targetPackage="com.crazy.training"android:targetClass="com.crazy.training.ui.MainActivity"></intent></Preference>

三、PreferenceScreen和PreferenceCategory

PreferenceScreen和PreferenceCategory没有新增的属性,所有属性全部继承自Preference。其中PreferenceScreen作为顶级容器,PreferenceCategory作为次级容器(类似于SQL Group by功能暂且这么理解吧),虽然他们也是可以单独使用的,但是并不能响应onPreferenceClickonPreferenceChange事件。

布局和MainActivity的代码依然很简单和前面类似

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"android:title="PreferenceScreen">
<PreferenceCategory
    android:key="key_prerence"android:summary="Preference Categories Summary"android:title="Preference Categories">
</PreferenceCategory>
</PreferenceScreen>

这里写图片描述

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"android:title="PreferenceScreen">
<PreferenceCategory
    android:key="key_prerence"android:summary="Preference Categories Summary"android:title="Preference Categories"><CheckBoxPreference
        android:icon="@mipmap/ic_launcher"android:key="key_chkpreference"android:title="CheckBoxPreference"android:summary="CheckboxPreference summary"/><EditTextPreference
        android:icon="@mipmap/ic_blue_launcher"android:key="key_edtkpreference"android:title="EditPreference"android:summary="EditPreference summary"/>
</PreferenceCategory>
</PreferenceScreen>

这里写图片描述

四、RingtonePreference的应用

RingtonePreference起作用就是供我们选择系统铃声的,除了Preference共有的属性外还新增了自己的几个独特属性。

新增属性说明
android:ringtoneType铃声类型:ringtone、notification、all、alarm
android:showDefault布尔值是否显示默认铃声
android:showSilent布尔值是否显示静音

应用也很简单,与Preference大同小异(注意看图)

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"android:key="using_categories_in_root_screen"android:summary="Using Preference Categories"android:title="Categories"><RingtonePreference
        android:key="key_prerence"android:title="RingPreferece Title"android:summary="RingPreference Summary"/></PreferenceScreen>

这里写图片描述

五、Preference的管理

Preference的管理主要包含Preference的创建添加移除寻找特定Preference,Preference并没有直接提供相关替换的方法。

1、创建Preference

主要是通过各自对应Preference的构造方法或者直接在xml文件中定义来创建对应的Preference

2、addPreference添加Preference

添加只要是就是调用PreferenceGroup的addPreference(Preference preference)方法 来添加至容器PreferenceGroup。

3、findPreference寻找特定Preference

对于PreferenceActivityfindPreference(key)方法,我们只需要知道key值就可以找到同一xml文件下相应的Preference,勿需考虑层级和嵌套关系
这里写图片描述

4、removePreference或removeAll移除Preference

对于PreferenceGroupremovePreference(Preference preference)removeAll()方法,都是针对某个PreferenceGroup来处理的,所以我们必须考虑层级嵌套关系,可以分为两步:先找到PreferenceGroup和要删除的Preference,再调用PreferenceGroup的removePreference执行删除动作。

首先这是我们的布局

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"android:key="key_manage_prefs"><PreferenceCategory
        android:key="key_category"android:title="PreferenceCategory"><EditTextPreference
            android:key="key_edtprefs"android:title="EditTextPreference" /><PreferenceScreen
            android:key="key_child_prefscreen"android:title="Child PreferenceScreen"><CheckBoxPreference
                android:key="key_checkbox"android:title="CheckBoxPreference" /></PreferenceScreen></PreferenceCategory>
</PreferenceScreen>

测试主体代码

public class MainActivity extends PreferenceActivity {private Context mContext;private Preference preference;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);addPreferencesFromResource(R.xml.test_preference);//removePreferenceByKey();mContext=getApplicationContext();preference=findPreference("key_checkbox_child");//只要是同一个xml文件下的所有Preference都能通过key直接找到preference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {@Overridepublic boolean onPreferenceChange(Preference preference, Object newValue) {Toast.makeText(mContext, String.format("Preference的值为%s", newValue),Toast.LENGTH_LONG).show();return true;}});preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {@Overridepublic boolean onPreferenceClick(Preference preference) {Toast.makeText(mContext, "Preference Clicked",Toast.LENGTH_LONG).show();//getFragmentManager().beginTransaction().replace(android.R.id.content,new MainFragment()).commit();return false;}});}private void removePreferenceByKey(){/*PreferenceGroup preferenceGroup=(PreferenceGroup)findPreference("key_category");//先找到PreferenceGroupPreference preference=findPreference("key_edtprefs");//再找到要删除的Preference*//*(PreferenceGroup)findPreference("key_child_prefscreen").removePreference(findPreference("key_checkbox_child"));//执行删除key为key_checkbox_child的Preference**/getPreferenceScreen().removePreference(findPreference("key_category"));//删除掉key_category及对应节点下的所有节点//ERROR//getPreferenceScreen().removePreference(findPreference("key_edtprefs"));//无效,因为getPreferenceScreen获得的是当前的顶级容器,而key_edtprefs不是它的直接字节点((PreferenceGroup)findPreference("key_category")).removeAll();//仅删除掉key_category下对应Preference节点下的所有子节点}

这里写图片描述

小结

这篇文章主要介绍了Preference家族树中顶级成员和次级成员的应用和简单原理的说明,也基本把几乎所有相关的知识点都涉及了,Preference的基本语法都是一样的,区别在于各自不同的特性。


http://chatgpt.dhexx.cn/article/fNndikd0.shtml

相关文章

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);//开…

lspci是如何工作的

目录 前言lspci那么系统是怎么知道每个PCIe设备具体是哪个厂商的哪种设备的&#xff1f; 前言 出于好奇&#xff0c;看了看lspci的工作原理&#xff0c;操作系统是怎么认识这么多PCIe设备的&#xff1b; lspci lspci用于查看当前系统所连接的所有PCI/PCIe设备&#xff1b; …