用自己的身份做网站备案,wordpress短网址,网站建设方案 规划,集团公司网站欣赏一#xff0e;基础知识 我们在使用Android手机时#xff0c;可能会经常用到其中的设置界面#xff0c;如下所示#xff1a; 图1 Android系统中的设置界面 而且对于我们自己开发的一个完整的程序来说#xff0c;我们也会需要给用户提供一个设置界面使用户可以对程序的一些参… 一基础知识 我们在使用Android手机时可能会经常用到其中的设置界面如下所示 图1 Android系统中的设置界面 而且对于我们自己开发的一个完整的程序来说我们也会需要给用户提供一个设置界面使用户可以对程序的一些参数进行设置。因此我们就来学习下如何实现符合我们需要的一个设置界面及其背后的数据持久化功能。 二实例开发 2.1 SharedPreferences 在具体介绍Android的设置界面的实现之前我们先来介绍一下预备知识就是Android数据持久化方法中最简单的一种即使用Preferences的键值对存储方式。这种方式主要用来存储比较简单的一些数据而且是标准的Boolean、Int、Float、Long、String等类型。 android.content.SharedPreferences是一个接口用来获取和修改持久化存储的数据。有三种获取系统中保存的持久化数据的方式 1. public SharedPreferences getPreferences (int mode) 通过Activity对象获取获取的是本Activity私有的Preference保存在系统中的xml形式的文件的名称为这个Activity的名字因此一个Activity只能有一个属于这个Activity。 2. public SharedPreferences getSharedPreferences (String name, int mode) 因为Activity继承了ContextWrapper因此也是通过Activity对象获取但是属于整个应用程序可以有多个以第一参数的name为文件名保存在系统中。 3. public static SharedPreferences getDefaultSharedPreferences (Context context) PreferenceManager的静态函数保存PreferenceActivity中的设置属于整个应用程序但是只有一个Android会根据包名和PreferenceActivity的布局文件来起一个名字保存。 通过以上方式取得SharedPreferences后就可以对数据进行读取或者保存了。 保存方式如下 view plain copy to clipboard print ? String STORE_NAME Settings; SharedPreferences settings getSharedPreferences(STORE_NAME, MODE_PRIVATE); SharedPreferences.Editor editor settings.edit(); editor.putInt(sourceType, 0); editor.commit(); String STORE_NAME Settings; SharedPreferences settings getSharedPreferences(STORE_NAME, MODE_PRIVATE); SharedPreferences.Editor editor settings.edit(); editor.putInt(sourceType, 0); editor.commit(); 获得SharedPreferences如果需要进行保存等修改操作首先得通过其edit()方法获得SharedPreferences.Editor然后就可以通过putInt、putString等方法以键值对(key-value)的方式保存数据或者remove移除某个键(key)及调用clear方法删除所有内容。最后需要调用commit方法是使修改生效。 读取方式如下 view plain copy to clipboard print ? SharedPreferences settings getSharedPreferences(STORE_NAME, MODE_PRIVATE); int source settings.getInt(sorceType, 1); SharedPreferences settings getSharedPreferences(STORE_NAME, MODE_PRIVATE); int source settings.getInt(sorceType, 1); 读取就更加简单了只要获得SharedPreferences后就可以通过getInt、getString等方法获取对应键(key)保存着的数据如果没有找到key则返回第二个参数作为默认值。 2.2 PreferenceActivity 上面介绍SharedPreferences键值对保存的基础知识接着我们就可以来实现Android系统的设置界面。Android系统中和设置界面相关的包为android.preference其中有一个继承了ListActivity的PreferenceActivity。 下面我们就先实现一个如下图2的最简单的PreferenceActivity设置界面只有一个CheckBox选择选项选中时显示“Yes,I love you!”取消选择时显示“No,I am sorry.”。然后再介绍其具体的实现。 图2 PreferenceActivity界面 首先新建一个工程AndroidPreferenceDemo。 把extends Activity改为extends PreferenceActivity。 在res目录下新建一个xml文件夹接着在这个文件夹下新建一个取名为preferences.xml的File文件内容如下 view plain copy to clipboard print ? ?xml version1.0 encodingUTF-8? PreferenceScreen xmlns:androidhttp://schemas.android.com/apk/res/android android:titleSettings CheckBoxPreference android:titleLove me? android:summaryOnYes,I love you! android:summaryOffNo,I am sorry. android:defaultValuetrue /CheckBoxPreference /PreferenceScreen ?xml version1.0 encodingUTF-8?PreferenceScreen xmlns:androidhttp://schemas.android.com/apk/res/android android:titleSettingsCheckBoxPreference android:titleLove me? android:summaryOnYes,I love you!android:summaryOffNo,I am sorry.android:defaultValuetrue/CheckBoxPreference/PreferenceScreen 然后把java文件中的setContentView(R.layout.main);改为 addPreferencesFromResource(R.xml.preferences); 完成了最后可以运行试下效果。 Java文件的实现很简单继承PreferenceActivity后调用其public void addPreferencesFromResource (int preferencesResId) 方法从一个xml文件中获取preference然后显示为标准的设置界面。 因此我们只要在xml文件中布局好要显示的设置界面内容就可以了。 下面我们看下布局文件xml的内容。 对应的xml中可以使用的标签(Tag)可以分为两类一类是管理布局的显示如PreferenceScreen另一类是具体的设置内容如CheckBoxPreference。 PreferenceScreen可以显示一个完整的页面可以嵌套包含在PreferenceScreen标签里的内容都将以一个完整的页面显示。 我们学习一个PreferenceScreen的界面如下图3所示。 图3 PreferenceScreen相关的布局 当点击左图的选项时分别会以新的页面显示如中间和右图所示。 上面页面对应的xml布局文件如下所示 view plain copy to clipboard print ? ?xml version1.0 encodingUTF-8? PreferenceScreen xmlns:androidhttp://schemas.android.com/apk/res/android android:titleSettings PreferenceScreen xmlns:androidhttp://schemas.android.com/apk/res/android android:titleEmotions android:summarysettings about emotions CheckBoxPreference android:titleLove me? android:summaryOnYes,I love you! android:summaryOffNo,I am sorry. android:defaultValuetrue /CheckBoxPreference CheckBoxPreference android:titleHate me? android:summaryOnYes,I hate you! android:summaryOffNo,you are a good person. android:defaultValuefalse /CheckBoxPreference /PreferenceScreen PreferenceScreen xmlns:androidhttp://schemas.android.com/apk/res/android android:titleRelations android:summarysettings about relations CheckBoxPreference android:titleFamily? android:summaryOnYes,we are family! android:summaryOffNo,I am sorry. android:defaultValuetrue /CheckBoxPreference CheckBoxPreference android:titleFriends? android:summaryOnYes,we are friends! android:summaryOffNo,I am sorry. android:defaultValuefalse /CheckBoxPreference /PreferenceScreen /PreferenceScreen ?xml version1.0 encodingUTF-8?PreferenceScreen xmlns:androidhttp://schemas.android.com/apk/res/android android:titleSettingsPreferenceScreen xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:titleEmotionsandroid:summarysettings about emotionsCheckBoxPreference android:titleLove me? android:summaryOnYes,I love you!android:summaryOffNo,I am sorry.android:defaultValuetrue/CheckBoxPreferenceCheckBoxPreference android:titleHate me? android:summaryOnYes,I hate you!android:summaryOffNo,you are a good person.android:defaultValuefalse/CheckBoxPreference/PreferenceScreenPreferenceScreen xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:titleRelationsandroid:summarysettings about relationsCheckBoxPreference android:titleFamily? android:summaryOnYes,we are family!android:summaryOffNo,I am sorry.android:defaultValuetrue/CheckBoxPreferenceCheckBoxPreference android:titleFriends? android:summaryOnYes,we are friends!android:summaryOffNo,I am sorry.android:defaultValuefalse/CheckBoxPreference/PreferenceScreen/PreferenceScreen 和管理布局显示相关的除了PreferenceScreen外还有一个常用的为PreferenceCategory我们把上面xml文件中间那两个PreferenceScreen改为PreferenceCategory就可以看到PreferenceCategory的显示效果了如下图4所示。 图4 PreferenceCategory相关的布局 可以看到PreferenceCategory是把包含的内容归为同一类但只是显示在一个页面中。 管理布局相关的两个标签可以使设置内容显示的更有条理但是更主要的还是具体设置相关的标签除了我们已经在使用的用于二选一的CheckBoxPreference外Android系统提供的还有以对话框显示的DialogPreference可以输入文本的EditTextPreference以列表方式显示供选择的ListPreference和设置铃声用的RingtonePreference。 下面我们选择比较常用的ListPreference来介绍下具体使用。 首先在res/values/文件夹下新建一个取名为array.xml的文件内容为 view plain copy to clipboard print ? ?xml version1.0 encodingutf-8? resources !-- 系统设置界面需要要到的数组 -- string-array nameauto_update_frequency_entry item10分钟/item item30分钟/item item1小时/item item12小时/item item24小时/item /string-array string-array nameauto_update_frequency_value item10/item item30/item item60/item item720/item item1440/item /string-array /resources ?xml version1.0 encodingutf-8?resources !-- 系统设置界面需要要到的数组 --string-array nameauto_update_frequency_entryitem10分钟/itemitem30分钟/itemitem1小时/itemitem12小时/itemitem24小时/item/string-arraystring-array nameauto_update_frequency_valueitem10/itemitem30/itemitem60/itemitem720/itemitem1440/item/string-array/resources 然后在res/values/strings.xml文件中添加 view plain copy to clipboard print ? !-- 统设置界面需要要到的字符串 -- string namesystem_settings系统设置/string string nameauto_update_setting自动更新设置/string string nameauto_update_switch_title自动更新/string string nameauto_update_switch_keyauto_update_switch/string string nameauto_update_switch_summary_on开启自动更新/string string nameauto_update_switch_summary_off关闭自动更新/string string nameauto_update_frequency_title更新频率/string string nameauto_update_frequency_keyauto_update_frequency/string string nameauto_update_frequency_default_value10/string string nameauto_update_frequency_summary设置自动更新的时间周期/string string namecancel取消/string !-- 统设置界面需要要到的字符串 -- string namesystem_settings系统设置/string string nameauto_update_setting自动更新设置/string string nameauto_update_switch_title自动更新/string string nameauto_update_switch_keyauto_update_switch/string string nameauto_update_switch_summary_on开启自动更新/string string nameauto_update_switch_summary_off关闭自动更新/string string nameauto_update_frequency_title更新频率/string string nameauto_update_frequency_keyauto_update_frequency/string string nameauto_update_frequency_default_value10/string string nameauto_update_frequency_summary设置自动更新的时间周期/stringstring namecancel取消/string 需要的数据现在准备好了下面我们来完成对应的xml文件。xml文件中各个标签的属性比较多虽然Android有代码自动补全功能但是还是使用Android提供的Structure界面来填写比较方便下面我们就以这个方式来完成。 在res/xml文件夹下新建一个Android XML File文件取名为preferencesii.xml类型选择PreferenceRoot Element选择PreferenceScreen。 在Structure方式显示时就会列出选中标签的所有属性然后就可以根据需要填写属性如下图5所示 图5 填写xml中Preference的属性 从上图我们可以看到一个Preference拥有的属性。其中Key为这个Preference的ID设置了才可以在代码中引用Title是显示的标题Summary是显示在标题下的文字介绍 一般在Dependency中填写一个CheckBoxPreference的Key这样就会在填写的那个CheckBoxPreference勾选时当前这个Preference才可用Default Value为初始值等等。 点击“Add”按钮就会添加新的标签我们依次添加一个CheckBoxPreference和ListPreference。属于CheckBoxPreference的特有属性主要为Summary On和Summary Off比较好理解。下面具体来看下ListPreference属性的填写 图6 ListPreference的属性 我们可以看到ListPreference除了继承自Preference的属性外还有自己ListPreference的属性和继承自DialogPreference的属性。其中属于ListPreference的属性有两个Entries填的为一个字符串数组是列表显示出来的值而Entry Values是长度对应的字符串数组是和Entries对应的具体的值。DialogPreference只要填一个Dialog title标题和一个取消按钮显示的字即可。在Preference属性的Dependency中我们填写上面一个CheckBoxPreference的Key这样就会只有在CheckBoxPreference勾选时这个ListPreference才有效。 图7 完整的xml显示 最后把java文件中的addPreferencesFromResource(R.xml.preferences);改为addPreferencesFromResource(R.xml.preferencesii); 保存运行看下效果。 图8 ListPreference显示 2.3 OnPreferenceChangeListener 以上我们分别介绍了Preference对数据的保存及PreferenceActivity设置界面。当PreferenceActivity中的内容改变时Android系统会自动进行保存和持久化维护我们只需要在要用的设置界面中数据的地方进行读取就可以了。同时Android还提供了OnPreferenceClickListener和OnPreferenceChangeListener两个与Preference相关的监听接口当PreferenceActivity中的某一个Preference进行了点击或者改变的操作时都会回调接口中的函数这样可以第一个时间向其他Activity等通知系统设置进行了改变。 下面我们以一个具体的Demo说明PreferenceActivity和其监听接口的使用。 新建一个工程AndroidPreferenceDemoII并按上面的步骤添加xml文件夹和其内容Preferenceii.xml还有values文件夹中的array.xml和strings.xml。 新建一个名为Settings的class内容为 view plain copy to clipboard print ? //继承PreferenceActivity并实现OnPreferenceChangeListener和OnPreferenceClickListener监听接口 public class Settings extends PreferenceActivity implements OnPreferenceChangeListener, OnPreferenceClickListener{ //定义相关变量 String updateSwitchKey; String updateFrequencyKey; CheckBoxPreference updateSwitchCheckPref; ListPreference updateFrequencyListPref; Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //从xml文件中添加Preference项 addPreferencesFromResource(R.xml.preferencesii); //获取各个Preference updateSwitchKey getResources().getString(R.string.auto_update_switch_key); updateFrequencyKey getResources().getString(R.string.auto_update_frequency_key); updateSwitchCheckPref (CheckBoxPreference)findPreference(updateSwitchKey); updateFrequencyListPref (ListPreference)findPreference(updateFrequencyKey); //为各个Preference注册监听接口 updateSwitchCheckPref.setOnPreferenceChangeListener(this); updateSwitchCheckPref.setOnPreferenceClickListener(this); updateFrequencyListPref.setOnPreferenceChangeListener(this); updateFrequencyListPref.setOnPreferenceClickListener(this); } Override public boolean onPreferenceChange(Preference preference, Object newValue) { // TODO Auto-generated method stub Log.v(SystemSetting, preference is changed); Log.v(Key_SystemSetting, preference.getKey()); //判断是哪个Preference改变了 if(preference.getKey().equals(updateSwitchKey)) { Log.v(SystemSetting, checkbox preference is changed); } else if(preference.getKey().equals(updateFrequencyKey)) { Log.v(SystemSetting, list preference is changed); } else { //如果返回false表示不允许被改变 return false; } //返回true表示允许改变 return true; } Override public boolean onPreferenceClick(Preference preference) { // TODO Auto-generated method stub Log.v(SystemSetting, preference is clicked); Log.v(Key_SystemSetting, preference.getKey()); //判断是哪个Preference被点击了 if(preference.getKey().equals(updateSwitchKey)) { Log.v(SystemSetting, checkbox preference is clicked); } else if(preference.getKey().equals(updateFrequencyKey)) { Log.v(SystemSetting, list preference is clicked); } else { return false; } return true; } } //继承PreferenceActivity并实现OnPreferenceChangeListener和OnPreferenceClickListener监听接口public class Settings extends PreferenceActivity implements OnPreferenceChangeListener, OnPreferenceClickListener{//定义相关变量String updateSwitchKey;String updateFrequencyKey;CheckBoxPreference updateSwitchCheckPref;ListPreference updateFrequencyListPref; Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //从xml文件中添加Preference项 addPreferencesFromResource(R.xml.preferencesii); //获取各个Preference updateSwitchKey getResources().getString(R.string.auto_update_switch_key); updateFrequencyKey getResources().getString(R.string.auto_update_frequency_key); updateSwitchCheckPref (CheckBoxPreference)findPreference(updateSwitchKey); updateFrequencyListPref (ListPreference)findPreference(updateFrequencyKey); //为各个Preference注册监听接口 updateSwitchCheckPref.setOnPreferenceChangeListener(this); updateSwitchCheckPref.setOnPreferenceClickListener(this); updateFrequencyListPref.setOnPreferenceChangeListener(this); updateFrequencyListPref.setOnPreferenceClickListener(this); }Overridepublic boolean onPreferenceChange(Preference preference, Object newValue) {// TODO Auto-generated method stubLog.v(SystemSetting, preference is changed);Log.v(Key_SystemSetting, preference.getKey());//判断是哪个Preference改变了if(preference.getKey().equals(updateSwitchKey)){Log.v(SystemSetting, checkbox preference is changed);}else if(preference.getKey().equals(updateFrequencyKey)){Log.v(SystemSetting, list preference is changed);}else{//如果返回false表示不允许被改变return false;}//返回true表示允许改变return true;}Overridepublic boolean onPreferenceClick(Preference preference) {// TODO Auto-generated method stubLog.v(SystemSetting, preference is clicked);Log.v(Key_SystemSetting, preference.getKey());//判断是哪个Preference被点击了if(preference.getKey().equals(updateSwitchKey)){Log.v(SystemSetting, checkbox preference is clicked);}else if(preference.getKey().equals(updateFrequencyKey)){Log.v(SystemSetting, list preference is clicked);}else{return false;}return true;}} 主要是获取xml文件中的各个Preference然后为其注册监听接口最后在监听接口的回调函数中打印相关的信息。 接着在Manifest文件中对这个Activity进行注册 view plain copy to clipboard print ? activity android:name.Settings /activity activity android:name.Settings/activity 然后对AndroidPreferenceDemoII.java文件进行如下修改 view plain copy to clipboard print ? public class AndroidPreferenceDemoII extends Activity { /** Called when the activity is first created. */ // 菜单项 final private int menuSettingsMenu.FIRST; private static final int REQ_SYSTEM_SETTINGS 0; Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } //创建菜单 Override public boolean onCreateOptionsMenu(Menu menu) { // 建立菜单 menu.add(0, menuSettings, 2, 设置); return super.onCreateOptionsMenu(menu); } //菜单选择事件处理 Override public boolean onMenuItemSelected(int featureId, MenuItem item) { switch (item.getItemId()) { case menuSettings: //转到Settings设置界面 startActivityForResult(new Intent(this, Settings.class), REQ_SYSTEM_SETTINGS); break; default: break; } return super.onMenuItemSelected(featureId, item); } //Settings设置界面返回的结果 protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode REQ_SYSTEM_SETTINGS) { //获取设置界面PreferenceActivity中各个Preference的值 String updateSwitchKey getResources().getString(R.string.auto_update_switch_key); String updateFrequencyKey getResources().getString(R.string.auto_update_frequency_key); //取得属于整个应用程序的SharedPreferences SharedPreferences settings PreferenceManager.getDefaultSharedPreferences(this); Boolean updateSwitch settings.getBoolean(updateSwitchKey, true); String updateFrequency settings.getString(updateFrequencyKey, 10); //打印结果 Log.v(CheckBoxPreference_Main, updateSwitch.toString()); Log.v(ListPreference_Main, updateFrequency); } else { //其他Intent返回的结果 } } } public class AndroidPreferenceDemoII extends Activity { /** Called when the activity is first created. */// 菜单项final private int menuSettingsMenu.FIRST;private static final int REQ_SYSTEM_SETTINGS 0; Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } //创建菜单 Override public boolean onCreateOptionsMenu(Menu menu) {// 建立菜单 menu.add(0, menuSettings, 2, 设置);return super.onCreateOptionsMenu(menu); } //菜单选择事件处理 Overridepublic boolean onMenuItemSelected(int featureId, MenuItem item) { switch (item.getItemId()) { case menuSettings: //转到Settings设置界面 startActivityForResult(new Intent(this, Settings.class), REQ_SYSTEM_SETTINGS); break; default: break; } return super.onMenuItemSelected(featureId, item); } //Settings设置界面返回的结果 protected void onActivityResult(int requestCode, int resultCode, Intent data) {if(requestCode REQ_SYSTEM_SETTINGS){//获取设置界面PreferenceActivity中各个Preference的值 String updateSwitchKey getResources().getString(R.string.auto_update_switch_key); String updateFrequencyKey getResources().getString(R.string.auto_update_frequency_key); //取得属于整个应用程序的SharedPreferencesSharedPreferences settings PreferenceManager.getDefaultSharedPreferences(this);Boolean updateSwitch settings.getBoolean(updateSwitchKey, true);String updateFrequency settings.getString(updateFrequencyKey, 10);//打印结果Log.v(CheckBoxPreference_Main, updateSwitch.toString());Log.v(ListPreference_Main, updateFrequency);}else{//其他Intent返回的结果} }} 主要是添加一个设置菜单点击后转到设置界面当从设置界面返回后读取保存的内容并打印出来查看。 最后我们看一下运行的效果 图9 设置界面操作 操作的Log输出如下图10所示 图10 DDMS的LogCat输出 点击设置菜单转到设置界面后首先点击CheckBox输出前6行然后点击ListPreference输出3行当选择列表的第二个进行改变时再输出3行最后按返回键回到第一个页面打印出最后2行。 最后我们看一下这些设置参数在系统中的保存文件。在DDMS的File Explorer中查看data/data/com.ichliebephone文件夹我们可以看到有如下文件 图11 Preference保存的文件 把这个文件导出到电脑上可以看到起内容为 view plain copy to clipboard print ? ?xml version1.0 encodingutf-8 standaloneyes ? map string nameauto_update_frequency30/string boolean nameauto_update_switch valuetrue / /map ?xml version1.0 encodingutf-8 standaloneyes ?mapstring nameauto_update_frequency30/stringboolean nameauto_update_switch valuetrue //map 文件以map的方式保存了两个设置参数 三总结 我们学习了Android的Preference相关内容包括最基本的SharedPreferences的使用及进一步的PreferenceActivity设置界面的介绍最后根据以上的内容完成了一个简单的Demo。 Preference键值对的方式是Android最简单的一种数据持久化方式虽然比较简单但是也比较实用特别是在保存小量的数据时。Android上的功能更加强大相对也更加复杂的SQLite数据保存方式我们以后接着学习。 文章对应的完整代码例子可以在这里下载 http://download.csdn.net/source/2728956