reference preparation_Preferences

reference preparation_Preferences在上篇文章中我们讲述的是Android5.1Settings的源码解析http://blog.csdn.net/dongxianfei/article/details/51979922,其中在介绍到Android的SubSetting时,我们说到基本上都是使用的PreferenceFragment技术,今天我们就来了解一下关于PreferenceFragment相关的技术吧。

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

在上篇文章中我们讲述了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吧。

首先来看应用的主界面:

reference preparation_Preferencesreference preparation_Preferences

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

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

public class PrefFragment extends PreferenceFragment {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		addPreferencesFromResource(R.xml.preferences);
	}
//重写的以下方法请看后面讲解
	@Override
	public 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 {

	@Override
	protected 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" >
        <CheckBoxPreference
            android:key="checkbox_preference"
            android:summary="是否勾选复选框"
            android:title="我是复选框" />
    </PreferenceCategory>

    <!-- 单独一个Switch开关 -->
    <PreferenceCategory android:title="我是Switch" >
        <SwitchPreference
            android:key="switch_preference"
            android:summary="是否打开我呢?"
            android:summaryOff="关闭"
            android:summaryOn="打开"
            android:switchTextOff="开关被关闭了"
            android:switchTextOn="开关被打开了"
            android:title="开关" />
    </PreferenceCategory>
    
    <!-- 很多选项的综合 -->
    <PreferenceCategory android:title="大综合" >
        <EditTextPreference
            android:dialogTitle="请输入你的名字"
            android:key="edittext_preference"
            android:summary="这是一个编辑框"
            android:title="我是编辑框" />

        <ListPreference
            android:dialogTitle="请选择一项"
            android:entries="@array/cities"
            android:entryValues="@array/cities"
            android:key="single_list_preference"
            android:summary="这是一个单选列表"
            android:title="我是单选框" />

        <MultiSelectListPreference
            android:dialogTitle="请选择一项"
            android:entries="@array/cities"
            android:entryValues="@array/cities"
            android:key="multi_list_preference"
            android:summary="这是一个多选列表"
            android:title="我是多选框" />

        <RingtonePreference
            android:key="ringtone_preference"
            android:ringtoneType="all"
            android:showSilent="true"
            android:summary="选择各种手机铃声"
            android:title="铃声" />

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

    <!-- 调试onPreferenceTreeClick接口 -->
    <PreferenceCategory android:title="联动设置" >
        <CheckBoxPreference
            android:key="select_linkage"
            android:title="是否选择联动" />

        <ListPreference
            android: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" >
        <CheckBoxPreference
            android:key="checkbox_preference"
            android:summary="是否勾选复选框"
            android:title="我是复选框" />
    </PreferenceCategory>

    <!-- 单独一个Switch开关 -->
    <PreferenceCategory android:title="我是Switch" >
        <SwitchPreference
            android:key="switch_preference"
            android:summary="是否打开我呢?"
            android:summaryOff="关闭"
            android:summaryOn="打开"
            android:switchTextOff="开关被关闭了"
            android:switchTextOn="开关被打开了"
            android:title="开关" />
    </PreferenceCategory>

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

reference preparation_Preferences

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

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

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

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

<!-- 很多选项的综合 -->
    <PreferenceCategory android:title="大综合" >
        <EditTextPreference
            android:dialogTitle="请输入你的名字"
            android:key="edittext_preference"
            android:summary="这是一个编辑框"
            android:title="我是编辑框" />

        <ListPreference
            android:dialogTitle="请选择一项"
            android:entries="@array/cities"
            android:entryValues="@array/cities"
            android:key="single_list_preference"
            android:summary="这是一个单选列表"
            android:title="我是单选框" />

        <MultiSelectListPreference
            android:dialogTitle="请选择一项"
            android:entries="@array/cities"
            android:entryValues="@array/cities"
            android:key="multi_list_preference"
            android:summary="这是一个多选列表"
            android:title="我是多选框" />

        <RingtonePreference
            android:key="ringtone_preference"
            android:ringtoneType="all"
            android:showSilent="true"
            android:summary="选择各种手机铃声"
            android:title="铃声" />

        <PreferenceScreen
            android:summary="是否能打开页面"
            android:title="打开页面" >
            <intent
                android:action="android.intent.action.VIEW"
                android:data="http://www.baidu.com" />
        </PreferenceScreen>
    </PreferenceCategory>

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

reference preparation_Preferences

然后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>

最后的运行效果图如下:

reference preparation_Preferences

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

效果图如下:

reference preparation_Preferences

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

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

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

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

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

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

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

效果图如下:

reference preparation_Preferences

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

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

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

<!-- 调试onPreferenceTreeClick接口 -->
    <PreferenceCategory android:title="联动设置" >
        <CheckBoxPreference
            android:key="select_linkage"
            android:title="是否选择联动" />

        <ListPreference
            android:dialogTitle="请选择一个城市"
            android:entries="@array/cities"
            android:entryValues="@array/cities"
            android:key="select_city"
            android:summary="我是否能选择看联动设置"
            android:title="是否能选择" />
    </PreferenceCategory>

运行的效果图如下:

reference preparation_Preferencesreference preparation_Preferences
 

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/196237.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 文本分类算法之–贝叶斯文本分类算法[通俗易懂]

    文本分类算法之–贝叶斯文本分类算法[通俗易懂]文本分类过程例如文档:GoodgoodstudyDaydayup可以用一个文本特征向量来表示,x=(Good,good,study,Day,day,up)。在文本分类中,假设我们有一个文档d∈X,类别c又称为标签。我们把一堆打了标签的文档集合作为训练样本,∈X×C。例如:={BeijingjoinstheWorldTradeOrganization,C

  • 大数据可视化的方法、挑战及进展[通俗易懂]

    大数据可视化的方法、挑战及进展[通俗易懂]大数据可视化的方法、挑战及进展摘要:在简化数据量和降低大数据应用的复杂性中,大数据分析发挥着关键的作用。可视化是其中一个重要的途径,它能够帮助大数据获得完整的数据视图并挖掘数据的价值。大数据分析和可视化应该无缝连接,这样才能在大数据应用中发挥最大的功效。这篇文章将介绍一些常规的数据可视化方法以及在大数据应用领域突破常规的可视化手段,也会讨论大数据可视化带来的挑战,同时介绍大数据可视化领域新的方

  • Pycharm 实现远程部署和调试,原来这么简单「建议收藏」

    Pycharm 实现远程部署和调试,原来这么简单「建议收藏」一般代码本地调试完成后,需要运行到服务器上,比如自动化测试脚本、爬虫脚本等,所以第一步需要将项目上传到服务器,然后在服务器上进行调试和运行。但是需要长期维护和开发的项目,这样就繁琐了很多,并且我们时常要维护多个测试或者开发环境,每个环境的Python版本和依赖包有可能还存在差异,这样的话,每次更新需要花费的时间就更多了。其实,很多的编辑器都考虑到这个问题,可以实现远程调试,比如Pycharm、Vscode等。Pycharm可以进行远程部署项目(上传和下载),还可以通过配置远程解释器进行远程调..

  • Fielddata is disabled on text fields by default. Set fielddata=true on [Tag] in order to load field

    Fielddata is disabled on text fields by default. Set fielddata=true on [Tag] in order to load field

  • redis 源代码分析(一) 内存管理

    redis 源代码分析(一) 内存管理

    2021年11月30日
  • GTest问题_itest.n z

    GTest问题_itest.n z1、cmkae出现”C:/Users/xxx/gcc/bin/gcc.exe”isnotabletocompileasimpletestprogram.问题在camke时添加-DCMAKE_C_COMPILER=gcc,-DCMAKE_C_COMPILER=gcc-DCMAKE_CXX_COMPILER=g++,-DCMAKE_MAKE_PROGRAM=make指定gcc、g++与make2、测试私有成员函数出现__xfer_bufptrsredeclaredwithdif

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号