首选项这个名词对于熟悉Android的朋友们一定不会感到陌生,它经常用来设置软件的运行参数。

Android提供了一种健壮并且灵活的框架来处理首选项。它提供了简单的API来隐藏首选项的读取和持久化,并且提供了一个优雅的首选项界面。

首先,我们来看下面这款软件的首选项界面:

这款软件使用了好几种类型的首选项,每一种首选项都有其独特的用法,下面我们来了解一下几种常见的首选项:

CheckBoxPreference:用来打开或关闭某个功能

ListPreference:用来从多个选项中选择一个值;

EditTextPreference:用来配置一段文字信息;

Preference:用来执行相关的自定义操作(上图中的清除缓存、历史记录、表单、cookie都属于此项);

RingtonePreference:专门用来为用户设置铃声。

当我们使用首选项框架时,用户每更改一项的值后,系统就会立即在/data/data/[PACKAGE_NAME]/shared_prefs下生成一个[PACKAGE_NAME]_preferences.xml的文件,文件会记录最新的配置信息。

那么如何使用首选想框架呢?我们需要以下几步操作:

1.建立一个首选项的xml配置文件,放在项目的/res/xml目录下面;

2.新建一个Activity,继承android.preference.PreferenceActivity,然后在onCreate方法中加载我们的首选项配置文件。

下面,我就为大家演示一下首选项框架的配置和使用:

我们新建一个prefs项目,项目结构如下:

我们要实现的功能跟上面那款软件的很相似,下面我来说明一下这个项目的整体流程:

1.主界面。显示用户昵称,有三个参数,昵称文字、字体大小和背景颜色。首次进入时,使用默认值。

2.按下menu键中的settings项,跳转到首选项页面,进行参数选择。

3.按下返回键,返回主界面,设定后的参数生效。

首先,让我们来看一下主界面的配置文件,非常简单,就一个TextView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/textView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:textColor="#FF0000"/>
</LinearLayout>

然后,我们需要在主界面里根据配置参数设置TextView的外观以及背景,MainActivity.java代码如下:

package com.scott.prefs;  

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView; public class MainActivity extends Activity { private static final int SETTINGS_ID = 0;
private static final int EXIT_ID = 1; private TextView textView; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView) findViewById(R.id.textView);
showSettings();
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, SETTINGS_ID, 0, "Settings");
menu.add(0, EXIT_ID, 0, "Quit");
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == SETTINGS_ID) {
Intent intent = new Intent(MainActivity.this, PrefsActivity.class);
//如果requestCode >= 0 则返回结果时会回调 onActivityResult()方法
startActivityForResult(intent, 1);
} else {
finish();
}
return true;
} @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
showSettings();
} private void showSettings() {
String prefsName = getPackageName() + "_preferences"; //[PACKAGE_NAME]_preferences
SharedPreferences prefs = getSharedPreferences(prefsName, Context.MODE_PRIVATE); String nickName = prefs.getString("nickName", "机器人");
textView.setText("欢迎您:" + nickName); boolean nightMode = prefs.getBoolean("nightMode", false);
textView.setBackgroundColor(nightMode ? Color.BLACK : Color.WHITE); String textSize = prefs.getString("textSize", "0");
if (textSize.equals("0")) {
textView.setTextSize(18f);
} else if (textSize.equals("1")) {
textView.setTextSize(22f);
} else if (textSize.equals("2")) {
textView.setTextSize(36f);
}
}
}

可以看到,进入主界面之后会根据[PACKAGE_NAME]_preferences获取首选项配置信息,如果是首次进入,则使用默认值,下面就是我们首次进入主界面时的画面:

可以看到,我们初次进入的界面时昵称为“机器人”,字的背景为白色,字的大小为18号。

然后按下Settings之后,我们就可以进行首选项的配置了,让我们先来看一下settings.xml的配置:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="settings"
android:title="软件设置">
<PreferenceCategory
android:key="basic"
android:title="基本设置">
<EditTextPreference
android:key="nickName"
android:title="昵称"
android:defaultValue="机器人"/>
<CheckBoxPreference
android:key="nightMode"
android:title="夜间模式"
android:summaryOn="已启用"
android:summaryOff="未启用"/>
<ListPreference
android:key="textSize"
android:title="文字大小"
android:dialogTitle="文字大小"
android:entries="@array/textSize_entry"
android:entryValues="@array/textSize_entry_value"
android:defaultValue="0"/>
</PreferenceCategory>
<PreferenceCategory
android:key="clean"
android:title="清除记录">
<Preference
android:key="cleanHistory"
android:title="清除历史记录" />
</PreferenceCategory>
</PreferenceScreen>

其中,最外层是PreferenceScreen标签,代表一系列首选项的集合;然后,我们注意到PreferenceCategory这一项,此标签代表一个类别,可以包含多个首选项;最后就是我们用于配置参数的首选项了。需要了解的是,PreferenceScreen也可以嵌套使用,也就是说上面的PreferenceCategory可以替换成PreferenceScreen。

此外,我们还需要了解一下文件中出现的几个常用标签属性:

android:key  选项的名称或键

android:title  选项的标题

android:summary  选项的简短摘要

android:entries  列表项的文本

android:entryValues  列表中每一项的值

android:dialogTitle  对话框标题

android:defalutValue  列表中选项的默认值

对于CheckBoxPreference还有两个特殊的属性

android:summaryOn  选项被选中时显示的摘要

android:summaryOff  选项未选中时显示的摘要

我们还可以看到,在ListPreference中,entries来自于textSize_entry,而entryValues来自于textSize_entry_value,这两项都在/res/values目录下的text_size.xml配置:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="textSize_entry">
<item>小</item>
<item>中</item>
<item>大</item>
</string-array>
<string-array name="textSize_entry_value">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
</resources>

配置完成之后,我们就剩下最后一步了,创建Activity,继承PreferenceActivity,加载首选项资源文件,处理相应的选项事件。

PrefsActivity.java代码如下:

package com.scott.prefs;  

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.widget.Toast; public class PrefsActivity extends PreferenceActivity implements Preference.OnPreferenceChangeListener { private EditTextPreference nickName;
private ListPreference textSize;
private Preference cleanHistory; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.setttings);
nickName = (EditTextPreference) findPreference("nickName");
textSize = (ListPreference) findPreference("textSize");
cleanHistory = findPreference("cleanHistory"); //为nickName和textSize注册Preference.OnPreferenceChangeListener监听事件
//当值更改时我们可以立即更新summary
nickName.setOnPreferenceChangeListener(this);
textSize.setOnPreferenceChangeListener(this); initSummary();
} //初始化summary
private void initSummary() {
nickName.setSummary(nickName.getText()); setTextSizeSummary(textSize.getValue());
} private void setTextSizeSummary(String textSizeValue) {
if (textSizeValue.equals("0")) {
textSize.setSummary("小");
} else if (textSizeValue.equals("1")) {
textSize.setSummary("中");
} else if (textSizeValue.equals("2")) {
textSize.setSummary("大");
}
} /**
* 重写PreferenceActivity的onPreferenceTreeClick方法
* 在首选项被点击时 做出相应处理操作
*/
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
if (preference == cleanHistory) {
new AlertDialog.Builder(this)
.setTitle("清除历史记录")
.setMessage("是否真的要清除历史记录?")
.setPositiveButton("是", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//cleaning history...
Toast.makeText(PrefsActivity.this, "清除成功", Toast.LENGTH_SHORT).show();
}
}).setNegativeButton("否", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).create().show();
}
return true;
} /**
* 重写Preference.OnPreferenceChangeListener的onPreferenceChange方法
* 当首选项的值更改时 做出相应处理操作
*/
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference == nickName) {
nickName.setSummary(newValue.toString());
} else if (preference == textSize) {
setTextSizeSummary(newValue.toString());
}
return true;
}
}

最后,别忘了在AndroidManifest.xml中加入此Activity配置信息:

<activity android:name=".PrefsActivity"/>

当然我们也可以配置一下<intent-filter></intent-filter>属性。

经过以上几步,我们的首选项配置就完成了,首次进入的界面如下:

可以看到,当我们更改了选项的值之后,摘要部分已经设置为最新值了,此时在我们应用下的shared_prefs目录中生成一个com.scott.prefs_preferences.xml文件,如图:

内容如下:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<boolean name="nightMode" value="true" />
<string name="nickName">scott</string>
<string name="textSize">2</string>
</map>

此时,我们按回退键,回到主界面,发现刚才的设置已经生效了

详解Android首选项框架的使用的更多相关文章

  1. 详解Android首选项框架ListPreference

    详解Android首选项框架ListPreference 原文地址 探索首选项框架 在深入探讨Android的首选项框架之前,首先构想一个需要使用首选项的场景,然后分析如何实现这一场景.假设你正在编写 ...

  2. 转:Android preference首选项框架

    详解Android首选项框架ListPreference 探索首选项框架 在 深入探讨Android的首选项框架之前,首先构想一个需要使用首选项的场景,然后分析如何实现这一场景.假设你正在编写一个应用 ...

  3. 首选项框架PreferenceFragment部分源代码分析

    由于要改一些settings里面的bug以及之前在里面有做过勿扰模式,准备对勿扰模式做一个总结,那先分析一下settings的源代码,里面的核心应该就是android3.0 上面的首选项框架Prefe ...

  4. 详解android:scaleType属性

    详解android:scaleType属性 转自:http://blog.csdn.net/encienqi/article/details/7913262    http://juliaailse. ...

  5. adb shell 命令详解,android

    http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...

  6. 详解Android Activity---启动模式

    相关的基本概念: 1.任务栈(Task)   若干个Activity的集合的栈表示一个Task.   栈不仅仅只包含自身程序的Activity,它也可以跨应用包含其他应用的Activity,这样有利于 ...

  7. Android Binder IPC详解-Android学习之旅(96)

    linux内存空间与BInder Driver Android进程和linux进程一样,他们只运行在进程固有的虚拟空间中.一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间 ,用户空间是 ...

  8. 详解Android中的四大组件之一:Activity详解

    activity的生命周期 activity的四种状态 running:正在运行,处于活动状态,用户可以点击屏幕,是将activity处于栈顶的状态. paused:暂停,处于失去焦点的时候,处于pa ...

  9. adb shell 命令详解,android, adb logcat

    http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...

随机推荐

  1. 利用beamer做幻灯片插入EPS图片的方法

      可以利用epstopdf宏包,在命令行下利用pdflatex带"-shell-escape"参数编译. 先插入epstopdf宏包:\usepackage{graphicx}\ ...

  2. GridView的TemplateField

    BoundField只能显示一个单独的数据字段.如果我们想要在一个GridView列中显示两个或者更多的数据字段的值的时候该怎么办呢? 1. GridView的一列同时显示数据源中的两个字段 现需要显 ...

  3. NYOJ 6.喷水装置(一)-贪心

    喷水装置(一) 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以 ...

  4. 51nod 1082 与7无关的数【打表/预处理】

    1082 与7无关的数 题目来源: 有道难题 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题  收藏  关注 一个正整数,如果它能被7整除,或者它的十进制表示法中某个 ...

  5. python3爬取百度图片(2018年11月3日有效)

    最终目的:能通过输入关键字进行搜索,爬取相应的图片存储到本地或者数据库 首先打开百度图片的网站,搜索任意一个关键字,比如说:水果,得到如下的界面 分析: 1.百度图片搜索结果的页面源代码不包含需要提取 ...

  6. 51nod 多重背包问题(动态规划)

    多重背包问题 一个背包,承量有限为W,有n种物体,第i种物体,价值Vi,占用重量为 Wi,且有Ci件,选择物品若干放入背包,使得总重量不超过背包的承重.总价值最大? 输入 第1行,2个整数,N和W中间 ...

  7. ASP.NET Core 2.2 基础知识(七) 选项模式

    承接上一篇 配置, 选项模式是专门用类来表示相关配置的服务. 基本选项配置 新建一个选项类,该类必须是包含无参数的构造函数的非抽象类. public class MyOptions { public ...

  8. C++—揭秘大牛博客一些不同凡人的写法

    天下之大,无奇不有,C++也是这样,今天小编来盘点几个有意思的代码,看看你认识几个?以后见到之后千万别装不认识. 一.基础篇——不一样的输出 1.cerr 输出 cout和cerr究竟有什么不同?这也 ...

  9. error和exception的区别

    ------解决方法--------------------------------------------------------了解异常与错误的区别,并且知道当你截获一个异常时,应该怎么办.   ...

  10. luogu P1313 计算系数

    二项式定理 组合数取膜 费马小定理 #include<iostream> using namespace std; #define mod 10007 #define int long l ...