1.何为首选项(Preference)?


Preference翻译成首选项有点生硬,但似乎也找到不其他更好的翻译,preference在英语的翻译是“偏爱,优先权”的意思。

Android 首选项是用来在Android中读取和存储一些数据,通常是配置项,当然完全还有其他方式能实现,比如数据库或者文件,为什么要使用Android中首选项,个人的理解是一些配置文件存在数据库中还要一张表来存,而且只有一行数据,还要自己写读取和保存方法,实在是累的很。在这提下,Android中的首选项最终是把数据按一定格式存到XMl文件中的,最后我们可以看到,数据的具体样子。


2.看一些今天我们Android首选项的例子效果图(会因为手机主题不同而变化)



Android 管理和组织首选项 (Preference) 附示例_第1张图片Android 管理和组织首选项 (Preference) 附示例_第2张图片Android 管理和组织首选项 (Preference) 附示例_第3张图片Android 管理和组织首选项 (Preference) 附示例_第4张图片

主Activity页面图1图2图3


点击主Activity的按钮就会进入图1,如果“喜欢吃水果选款”是勾选状态,下面两个点击就会分别弹出右边的样式,不是勾选状态下面两个就会置灰,不可用。

3. 赶快来看下如何实现的:)

1.首先是preference的布局文件 /res/xml/fruitoptions.xml

<?xml version="1.0" encoding="utf-8"?><PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >    <PreferenceCategory>        <CheckBoxPreference            android:defaultValue="true"            android:key="@string/love_fruit_pref"            android:summary="@string/love_fruit_summary"            android:title="@string/love_fruit_title" />    </PreferenceCategory>    <PreferenceCategory android:key="@string/detailSetting" >        <ListPreference            android:defaultValue="@string/fruit_option_default_value"            android:dialogTitle="@string/dialogTitle"            android:entries="@array/fruit_options"            android:entryValues="@array/fruit_options_values"            android:key="@string/selected_fruit_option"            android:summary="@string/listSummary"            android:title="@string/listTitle" />        <EditTextPreference            android:dialogTitle="@string/customed_fruit_dialogTitle"            android:key="@string/customed_fruit_pref"            android:summary="@string/customed_fruit_summary"            android:title="@string/customed_fruit_title" />    </PreferenceCategory></PreferenceScreen>
注意: /res/xml/fruitoptions.xml文件还需要 /res/values/strings.xml和 /res/values/arrays.xml支持

想尽可能多的把所有preference都举例出,所以这个xml文件中包含了CheckBoxPreference,ListPreference,EditTextPreference,当然还有RingtonePreference没有举例出,留给读者自己研究。

CheckBoxPreference,ListPreference,EditTextPreference,三个东西都有很多属性android:key,android:title等,android:key有点像普通控件中的android:id。

其他ListPreference中的android:entries 是列表项要显示出的文本,android:entryValues是列表项的键或者值,其他属性都是描述性的,大家可以根据字面英文意思来理解。

需要注意的是这个布局文件中用到了PreferenceScreen和PreferenceCategory。

PreferenceScreen是一些配置的集合,会在一个独立的屏幕中显示,大家可以试一下嵌套的PreferenceScreen,点击后会弹出一个新的屏幕

PreferenceCategory 正如我们图1中显示的那样,会有一个独立的外框来分开。

2.接下来是 /res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?><resources>    <string name="hello">Hello World, PreferenceDemoActivity!</string>    <string name="app_name">PreferenceDemo</string>    <string name="selected_fruit_option">selected_fruit_option</string>    <string name="fruit_option_default_value">1</string>    <string name="prefTitle">Preference 示例</string>    <string name="listTitle">选择一个水果</string>    <string name="dialogTitle">选择一个水果</string>    <string name="listSummary"></string>    <string name="btnText">点击打开配置</string>    <string name="detailSetting">detailSetting</string>        <string name="love_fruit_pref">like_fruit_pref</string>    <string name="love_fruit_title">喜欢吃水果?</string>    <string name="love_fruit_summary">喜欢吃水果的话就勾选此项:)</string>        <string name="customed_fruit_pref">customed_fruit_pref</string>    <string name="customed_fruit_title">你自己喜欢的水果?</string>    <string name="customed_fruit_summary">上面的还不够,写下你喜欢的:)</string>    <string name="customed_fruit_dialogTitle">我喜欢的水果</string></resources>

3.最后是/res/values/arrays.xml

<?xml version="1.0" encoding="utf-8"?><resources>    <string-array name="fruit_options">        <item>苹果</item>        <item>葡萄</item>        <item>橘子</item>    </string-array>    <string-array name="fruit_options_values">        <item>0</item>        <item>1</item>        <item>2</item>    </string-array></resources>

用@string/xxxx的方式来显示文字除了可以很容易的支持多种语言外还有很多好处,在获取key的时候也不需要打字符串,可以从strings.xml文件中读取,也不容易错。


4.好了到我们主Activity的布局代码了 /res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <Button        android:id="@+id/btnOpenSetting"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="@string/btnText" />    <TextView         android:id="@+id/result"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        /></LinearLayout>

很简单,一个按钮,一个显示我们的结果。

Activity的代码部分 PreferenceDemoActivity.java


package com.waitingfy.android;import android.app.Activity;import android.content.Intent;import android.content.SharedPreferences;import android.content.res.Resources;import android.os.Bundle;import android.preference.PreferenceManager;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class PreferenceDemoActivity extends Activity {private Button btnOpenSetting;private TextView resutlTextView;private SharedPreferences prefs;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);/* 两种方式获得 SharedPreferences */// prefs = getSharedPreferences("com.waitingfy.android_preferences", 0);prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());btnOpenSetting = (Button) findViewById(R.id.btnOpenSetting);resutlTextView = (TextView) findViewById(R.id.result);// 按钮绑定点击监听btnOpenSetting.setOnClickListener(new OnClickListener() {public void onClick(View v) {Intent intent = new Intent();intent.setClass(getApplicationContext(),com.waitingfy.android.FruitPreferenceActivity.class);startActivityForResult(intent, 0);}});setOptionText();}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);setOptionText();}/* * 从首选项中获得值,给控件赋值 */private void setOptionText() {StringBuilder resultString = new StringBuilder();Resources resources = this.getResources();// 从checkboxPreference获得值Boolean isLove = prefs.getBoolean(resources.getString(R.string.love_fruit_pref), true);// 从listPreference获得值String selectFruit = prefs.getString(resources.getString(R.string.selected_fruit_option),resources.getString(R.string.fruit_option_default_value));// 从 EditTextPreference获得值String customedFruit = prefs.getString(resources.getString(R.string.customed_fruit_pref), "");resultString.append(isLove.toString() + ",");resultString.append(selectFruit + ",");resultString.append(customedFruit);resutlTextView.setText(resultString);}}

都有注释,应该问题不大。

需要解析下的是有两种方法都可以得到SharedPreferences的实例

1. SharedPreferences prefs = getSharedPreferences("com.waitingfy.android_preferences", 0);
2. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

要从一个复选框首选项(CheckBoxPreference)中读取值用getBoolean()方法,将key传递给它就可以了,从ListPreference或EditPreference中读取值用getString(),也是传递一个key.


5.最后我们来看下载入首选项界面的代码是如何的FruitPreferenceActivity.java

通过这个代码我们就可以知道如何对首选项中的控件进行操作,不单单是读取他们的值。

package com.waitingfy.android;import android.content.res.Resources;import android.os.Bundle;import android.preference.CheckBoxPreference;import android.preference.Preference;import android.preference.Preference.OnPreferenceClickListener;import android.preference.PreferenceActivity;import android.preference.PreferenceCategory;public class FruitPreferenceActivity extends PreferenceActivity {    private CheckBoxPreference checkBoxPreference;    private PreferenceCategory preferenceCategory;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 从资源中添加preferencesaddPreferencesFromResource(R.xml.fruitoptions);Resources resources = this.getResources();//使用findpreference根据key返回特定的preference    checkBoxPreference = (CheckBoxPreference) findPreference(resources.getString(R.string.love_fruit_pref));    preferenceCategory = (PreferenceCategory) findPreference(resources.getString(R.string.detailSetting));    //checkbox绑定点击事件checkBoxPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {public boolean onPreferenceClick(Preference preference) {return SetPrefCategoryStateByCheckBoxState();}});SetPrefCategoryStateByCheckBoxState();}/* * 根据checkbox的状态改变一个prefcategory的状态 * */private boolean SetPrefCategoryStateByCheckBoxState() {if(checkBoxPreference.isChecked()){preferenceCategory.setEnabled(true);return true;}else {preferenceCategory.setEnabled(false);return false;}}}

代码也很清晰,主要是点击Checkboxpreference时我们要实现图1中下面两个选项的置灰效果,我们使用了findPreference,这个有点像findVIewById,只是这里传递进去的是key,不是Id,其他如Listpreference也可以通过findPreference来获取。


6.最后是我们的AndroidMinifest.xml文件

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.waitingfy.android"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk android:minSdkVersion="8" />    <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name" >        <activity            android:name=".PreferenceDemoActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activity android:name=".FruitPreferenceActivity">            <intent-filter>                <action android:name="com.waitingfy.android.FruitPreferenceActivity"/>                <category android:name="android.intent.category.PREFERENCE"/>            </intent-filter>        </activity>    </application></manifest>

AndroidMinifest.xml中只要注册两个Activity就行了,第二个Activity有个category可以关注下

7. 最后来看下我们数据存储的位置:

在/data/data/应用程序包名称/shared_prefs下

里面的内容:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?><map><string name="selected_fruit_option">2</string><boolean name="like_fruit_pref" value="false" /><string name="customed_fruit_pref">桃子</string></map>

好了,到这里这个Android首选项的示例就结束了,参考的是《精通Android2》的11章。

附上示例下载地址:PreferenceDemo

文章源地址 http://www.waitingfy.com/?p=9

更多相关文章

  1. android 资源文件学习
  2. Android 语音识别示例
  3. 大话企业级Android应用开发实战 文件下载
  4. mipmap和drawable文件夹的区别
  5. Android: /cache中的文件是怎么消失的
  6. Android APK文件结构 完整打包编译的流程 APK安装过程 详解

随机推荐

  1. Android(安卓)线性布局(LinearLayout)相关
  2. Android用户界面设计学习之旅-第六站
  3. Android 数据库之 SQLiteConnectionPool
  4. Android 对象序列化之 Parcelable 取代 S
  5. Android(安卓)Canvas绘图详解(图文)
  6. 去掉RecycleView或者ListView上下滑动阴
  7. 【原创】Proton在Android上的编译
  8. Android xml manifest属性详解
  9. 相对布局属性
  10. Android:实现无标题的两种方法