Android 管理和组织首选项 (Preference) 附示例
1.何为首选项(Preference)?
Preference翻译成首选项有点生硬,但似乎也找到不其他更好的翻译,preference在英语的翻译是“偏爱,优先权”的意思。
Android 首选项是用来在Android中读取和存储一些数据,通常是配置项,当然完全还有其他方式能实现,比如数据库或者文件,为什么要使用Android中首选项,个人的理解是一些配置文件存在数据库中还要一张表来存,而且只有一行数据,还要自己写读取和保存方法,实在是累的很。在这提下,Android中的首选项最终是把数据按一定格式存到XMl文件中的,最后我们可以看到,数据的具体样子。
2.看一些今天我们Android首选项的例子效果图(会因为手机主题不同而变化)
主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
更多相关文章
- android 资源文件学习
- Android 语音识别示例
- 大话企业级Android应用开发实战 文件下载
- mipmap和drawable文件夹的区别
- Android: /cache中的文件是怎么消失的
- Android APK文件结构 完整打包编译的流程 APK安装过程 详解