详解Android首选项框架的使用实例

首选项这个名词对于熟悉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> 

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

可以看到,昵称已经更改成“scott”,字的背景已更改为黑色,字的大小已更改为36号。

如果我们在首选项界面按下清除历史记录一项,将会出现一下界面:

原文链接:http://blog.csdn.net/liuhe688/article/details/6448423

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android百度地图实现搜索和定位及自定义图标绘制并点击时弹出泡泡

    一.问题描述 上一次我们使用百度地图实现基本的定位功能,接下来我们继续实现搜索和定位,并使用LocationOverlay绘制定位位置,同时展示如何使用自定义图标绘制并点击时弹出泡泡 如图所示: 二.编写MyApplication类 public class MyApplication extends Application { private static MyApplication mInstance = null; public boolean m_bKeyRight = true; pu

  • Android编程单选项框RadioGroup综合应用示例

    本文实例讲述了Android编程单选项框RadioGroup用法.分享给大家供大家参考,具体如下: 今天介绍的是RadioGroup 的组事件.RadioGroup 可将各自不同的RadioButton ,设限于同一个Radio 按钮组,同一个RadioGroup 组里的按钮,只能做出单一选择(单选题). 首先,我们先设计一个TextView Widget ,以及一个RadioGroup ,并将该RadioGroup 内放置两个RadioButton ,默认为都不选择,在程序运行阶段,利用onC

  • android PopupWindow 和 Activity弹出窗口实现方式

    本人小菜一个.目前只见过两种弹出框的实现方式,第一种是最常见的PopupWindow,第二种也就是Activity的方式是前几天才见识过.感觉很霸气哦.没想到,activity也可以做伪窗口. 先贴上最常见的方法,主要讲activity的方法. 一.弹出PopupWindow 复制代码 代码如下: /** * 弹出menu菜单 */ public void menu_press(){ if(!menu_display){ //获取LayoutInflater实例 inflater = (Layo

  • Android编程实现长按弹出选项框View进行操作的方法

    本文实例讲述了Android编程实现长按弹出选项框View进行操作的方法.分享给大家供大家参考,具体如下: 长按弹出选项框View进行操作 主要代码解释 private void showPopWindows(View v) { /** pop view */ View mPopView = LayoutInflater.from(this).inflate(R.layout.popup, null); final PopupWindow mPopWindow = new PopupWindow

  • android实现百度地图自定义弹出窗口功能

    我们使用百度地图的时候,点击地图上的Marker,会弹出一个该地点详细信息的窗口,如下左图所示,有时候,我们希望自己定义这个弹出窗口的内容,或者,干脆用自己的数据来构造这样的弹出窗口,但是,在百度地图最新的Android SDK中,没有方便操作这种弹出窗口的类,虽然有一个PopupOverlay,但是它只支持将弹出内容转化为不多于三个Bitmap,如果这个弹出窗口里想有按钮来响应点击事件,用这个就不能满足要求了,于是,看了一遍百度地图覆盖物的API,我决定用自定义View的方法来实现类似的效果,

  • android 弹出提示框的使用(图文实例)

    复制代码 代码如下: //删除全部 else if(id==R.id.btnDelet){ new AlertDialog.Builder(this).setTitle("删除提示框").setMessage("确认删除该数据?").setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, i

  • android 对话框弹出位置和透明度的设置具体实现方法

    例如,屏幕的上方或下方.要实现这种效果.就需要获得对话框的Window对象,获得这个Window对象有多种方法.最容易的就是直接通过AlertDialog类的getWindow方法来获得Window对象. 复制代码 代码如下: AlertDialog dialog = new AlertDialog.Builder(this).setTitle("title")                       .setMessage("message").create(

  • android底部弹出iOS7风格对话选项框(QQ对话框)--第三方开源之IOS_Dialog_Library

    先给大家展示下效果图,喜欢的朋友可以下载源码哦. 完成这个效果的是使用了 IOS_Dialog_Library 下载地址:http://xiazai.jb51.net/201509/yuanma/IOS_Dialog_Library(jb51.net) 下载后导入到Eclipse中,然后作为Library引入到自己的工程中,直接作为第三方控件使用. 测试代码: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/a

  • Android实现可输入数据的弹出框

    之前一篇文章,介绍了如何定义从屏幕底部弹出PopupWindow即<Android Animation实战之屏幕底部弹出PopupWindow>,写完之后,突然想起之前写过自定义内容显示的弹出框,就随手写了两个实例,分享出来: 第一种实现方式:继承Dialog  1.1 线定义弹出框要显示的内容:create_user_dialog.xml <?xml version="1.0" encoding="utf-8"?> <LinearLa

  • Android实现弹出登陆框的方案

    下面是我的实现经历: 1.首先,我是直接使用AlertDialog来实现,确定是,形状有点难看,而且获得Dialog里面的控件略显麻烦(因为我要做的登陆框有一定的布局),然后就给我就放弃了,可能因为我太水了,不能很好的使用它 2.然后我就使用PopupWindow来实现,界面是达到了我的要求,控件的获得通过Inflater就可以获得了相对较简单,但是有一个缺点就是,当点击输入的时候,对话框不会根据软键盘的位置而改变位置,网上搜了搜,还不能直接监听软键盘的出现和消失的事件消息,挣扎了一个下午,果断

  • Android弹出窗口实现方法

    本文实例讲述了Android弹出窗口实现方法.分享给大家供大家参考,具体如下: 直接上代码: /** * 弹窗--新手指引 * @param cxt * @param id 资源编号 * @create_time 2011-7-27 下午05:12:49 */ public static void displayWindow(Context cxt, int id) { final TextView imgTV = new TextView(cxt.getApplicationContext()

  • android弹出activity设置大小的方法

    如何设置Activity的大小,让你的窗口看起来不再是全屏的.有些网友可能知道通过主题比如Theme.Dialog来实现,不过告诉大家设置Activity不再全屏显示的原理.Android Theme也主要是通过定义Style来实现的,实现的原理大家可以直接看Android Framework中的定义,今天给一种更简单,但相对灵活的方法,比如不要Theme.Dialog中的边框,下面就一起来看下自定义Activity 大小的实现方法. 1. 创建一个样式文件到你的工程,保存在在res/value

  • Android实现弹出键盘的方法

    本文实例讲述了Android实现弹出键盘代码,是一个非常实用的功能.代码非常简洁.分享给大家供大家参考. 具体功能代码如下: Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { InputMethodManager m = (InputMethodManager) editText.getContext().getSystemService(Context.INPUT_

随机推荐