安卓开发学习笔记(1) preferences实现设置界面

时间:2022-10-28 22:38:09

https://blog.csdn.net/ichliebephone/article/details/5916320


今天在做一个设置界面的时候,我陷入了长思,到底如何才能把设置界面做的好看呢。于是我在网络的海洋中,发现了preferences,现在来开始学习他。

一、

    Preferences是一个自带数据持久化功能的东西

二、

    

2.1 SharedPreferences

    在具体介绍Android的设置界面的实现之前,我们先来介绍一下预备知识,就是Android数据持久化方法中最简单的一种,即使用Preferences的键值对存储方式。这种方式主要用来存储比较简单的一些数据,而且是标准的BooleanIntFloatLongString等类型。

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后就可以对数据进行读取或者保存了。

String STORE_NAME = "Settings";  
SharedPreferences settings = getSharedPreferences(STORE_NAME, MODE_PRIVATE);  
SharedPreferences.Editor editor = settings.edit();  
editor.putInt("sourceType", 0);  
 editor.commit(); 
SharedPreferences settings = getSharedPreferences(STORE_NAME, MODE_PRIVATE);  
 int source = settings.getInt("sorceType", 1); 

2.2 PreferenceActivity

    首先,把Activity的继承改为PreferenceActivity, res目录下新建一个xml文件夹,接着在这个文件夹下新建一个取名为preferences.xmlFile文件,内容如下:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <PreferenceScreen   
  3.     xmlns:android="http://schemas.android.com/apk/res/android"   
  4.     android:title="Settings">  
  5.     <CheckBoxPreference   
  6.         android:title="Love me?"   
  7.         android:summaryOn="Yes,I love you!"  
  8.         android:summaryOff="No,I am sorry."  
  9.         android:defaultValue="true">  
  10.     </CheckBoxPreference>  
  11. </PreferenceScreen>  

或者

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <PreferenceScreen   
  3.     xmlns:android="http://schemas.android.com/apk/res/android"   
  4.     android:title="Settings">  
  5.     <PreferenceScreen   
  6.         xmlns:android="http://schemas.android.com/apk/res/android"  
  7.         android:title="Emotions"  
  8.         android:summary="settings about emotions">  
  9.         <CheckBoxPreference    
  10.             android:title="Love me?"   
  11.             android:summaryOn="Yes,I love you!"  
  12.             android:summaryOff="No,I am sorry."  
  13.             android:defaultValue="true">  
  14.         </CheckBoxPreference>  
  15.         <CheckBoxPreference   
  16.             android:title="Hate me?"   
  17.             android:summaryOn="Yes,I hate you!"  
  18.             android:summaryOff="No,you are a good person."  
  19.             android:defaultValue="false">  
  20.         </CheckBoxPreference>       
  21.     </PreferenceScreen>  
  22.     <PreferenceScreen   
  23.         xmlns:android="http://schemas.android.com/apk/res/android"  
  24.         android:title="Relations"  
  25.         android:summary="settings about relations">  
  26.         <CheckBoxPreference   
  27.             android:title="Family?"   
  28.             android:summaryOn="Yes,we are family!"  
  29.             android:summaryOff="No,I am sorry."  
  30.             android:defaultValue="true">  
  31.         </CheckBoxPreference>  
  32.         <CheckBoxPreference   
  33.             android:title="Friends?"   
  34.             android:summaryOn="Yes,we are friends!"  
  35.             android:summaryOff="No,I am sorry."  
  36.             android:defaultValue="false">  
  37.         </CheckBoxPreference>       
  38.     </PreferenceScreen>     
  39. </PreferenceScreen>  

在上面的xml中,出现了和管理布局显示相关的除了PreferenceScreen外,还有一个常用的为PreferenceCategory,我们把上面xml文件中间那两个PreferenceScreen改为PreferenceCategory就可以看到PreferenceCategory的显示效果了。

接下来说一下ListPreferences的用法:

首先在res/values/文件夹下新建一个取名为array.xml的文件,内容为:

[xhtml]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <!-- 系统设置界面需要要到的数组 -->  
  4.     <string-array name="auto_update_frequency_entry">  
  5.         <item>10分钟</item>  
  6.         <item>30分钟</item>  
  7.         <item>1小时</item>  
  8.         <item>12小时</item>  
  9.         <item>24小时</item>     
  10.     </string-array>  
  11.     <string-array name="auto_update_frequency_value">  
  12.         <item>10</item>  
  13.         <item>30</item>  
  14.         <item>60</item>  
  15.         <item>720</item>  
  16.         <item>1440</item>     
  17.     </string-array>  
  18.     </resources>  

然后在res/values/strings.xml文件中添加:

[xhtml]  view plain  copy
  1. <!-- 统设置界面需要要到的字符串 -->  
  2.     <string name="system_settings">系统设置</string>  
  3.     <string name="auto_update_setting">自动更新设置</string>  
  4.     <string name="auto_update_switch_title">自动更新</string>  
  5.     <string name="auto_update_switch_key">auto_update_switch</string>  
  6.     <string name="auto_update_switch_summary_on">开启自动更新</string>  
  7.     <string name="auto_update_switch_summary_off">关闭自动更新</string>  
  8.     <string name="auto_update_frequency_title">更新频率</string>  
  9.     <string name="auto_update_frequency_key">auto_update_frequency</string>  
  10.     <string name="auto_update_frequency_default_value">10</string>  
  11.         <string name="auto_update_frequency_summary">设置自动更新的时间周期</string>  
  12.     <string name="cancel">取消</string> 

然后在xml中新建preferencesii:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:title="@string/system_settings">
    <CheckBoxPreference
        android:key="@string/auto_update_switch_key"
        android:title="@string/auto_update_switch_title"
        android:summaryOn="@string/auto_update_switch_summary_on"
        android:summaryOff="@string/auto_update_switch_summary_off"
        android:defaultValue="true">
    </CheckBoxPreference>
    <ListPreference
        android:title="@string/auto_update_frequency_title"
        android:key="@string/auto_update_frequency_key"
        android:defaultValue="@string/auto_update_frequency_default_value"
        android:summary="@string/auto_update_frequency_summary"
        android:entries="@array/auto_update_frequency_entry"
        android:entryValues="@array/auto_update_frequency_value"
        android:dialogTitle="@string/auto_update_frequency_title">
    </ListPreference>
</PreferenceScreen>
三、

上我们分别介绍了Preference对数据的保存及PreferenceActivity设置界面。当PreferenceActivity中的内容改变时,Android系统会自动进行保存和持久化维护,我们只需要在要用的设置界面中数据的地方进行读取就可以了。同时Android还提供了OnPreferenceClickListenerOnPreferenceChangeListener两个与Preference相关的监听接口,当PreferenceActivity中的某一个Preference进行了点击或者改变的操作时,都会回调接口中的函数,这样可以第一个时间向其他Activity等通知系统设置进行了改变。

下面我们以一个具体的Demo说明PreferenceActivity和其监听接口的使用。

    新建一个工程AndroidPreferenceDemoII,并按上面的步骤添加xml文件夹和其内容Preferenceii.xml,还有values文件夹中的array.xmlstrings.xml

    新建一个名为Settingsclass,内容为:

  1. //继承PreferenceActivity,并实现OnPreferenceChangeListener和OnPreferenceClickListener监听接口  
  2. public class Settings extends PreferenceActivity implements OnPreferenceChangeListener,   
  3. OnPreferenceClickListener{  
  4.     //定义相关变量  
  5.     String updateSwitchKey;  
  6.     String updateFrequencyKey;  
  7.     CheckBoxPreference updateSwitchCheckPref;  
  8.     ListPreference updateFrequencyListPref;  
  9.     @Override  
  10.     public void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         //从xml文件中添加Preference项  
  13.         addPreferencesFromResource(R.xml.preferencesii);  
  14.         //获取各个Preference  
  15.         updateSwitchKey = getResources().getString(R.string.auto_update_switch_key);  
  16.         updateFrequencyKey = getResources().getString(R.string.auto_update_frequency_key);  
  17.         updateSwitchCheckPref = (CheckBoxPreference)findPreference(updateSwitchKey);  
  18.         updateFrequencyListPref = (ListPreference)findPreference(updateFrequencyKey);  
  19.         //为各个Preference注册监听接口  
  20.         updateSwitchCheckPref.setOnPreferenceChangeListener(this);  
  21.         updateSwitchCheckPref.setOnPreferenceClickListener(this);  
  22.         updateFrequencyListPref.setOnPreferenceChangeListener(this);  
  23.         updateFrequencyListPref.setOnPreferenceClickListener(this);         
  24.     }  
  25.     @Override  
  26.     public boolean onPreferenceChange(Preference preference, Object newValue) {  
  27.         // TODO Auto-generated method stub  
  28.         Log.v("SystemSetting""preference is changed");  
  29.         Log.v("Key_SystemSetting", preference.getKey());  
  30.         //判断是哪个Preference改变了  
  31.         if(preference.getKey().equals(updateSwitchKey))  
  32.         {  
  33.             Log.v("SystemSetting""checkbox preference is changed");  
  34.         }  
  35.         else if(preference.getKey().equals(updateFrequencyKey))  
  36.         {  
  37.             Log.v("SystemSetting""list preference is changed");  
  38.         }  
  39.         else  
  40.         {  
  41.             //如果返回false表示不允许被改变  
  42.             return false;  
  43.         }  
  44.         //返回true表示允许改变  
  45.         return true;  
  46.     }  
  47.     @Override  
  48.     public boolean onPreferenceClick(Preference preference) {  
  49.         // TODO Auto-generated method stub  
  50.         Log.v("SystemSetting""preference is clicked");  
  51.         Log.v("Key_SystemSetting", preference.getKey());  
  52.         //判断是哪个Preference被点击了  
  53.         if(preference.getKey().equals(updateSwitchKey))  
  54.         {  
  55.             Log.v("SystemSetting""checkbox preference is clicked");  
  56.         }  
  57.         else if(preference.getKey().equals(updateFrequencyKey))  
  58.         {  
  59.             Log.v("SystemSetting""list preference is clicked");  
  60.         }  
  61.         else  
  62.         {  
  63.             return false;  
  64.         }  
  65.         return true;  
  66.     }  

其中change方法时在设置有改变的时候才会出发,click就是点击的时候会触发,要注意。

  1. public class AndroidPreferenceDemoII extends Activity {  
  2.     /** Called when the activity is first created. */  
  3.     // 菜单项  
  4.     final private int menuSettings=Menu.FIRST;  
  5.     private static final int REQ_SYSTEM_SETTINGS = 0;    
  6.     @Override  
  7.     public void onCreate(Bundle savedInstanceState) {  
  8.         super.onCreate(savedInstanceState);  
  9.         setContentView(R.layout.main);  
  10.     }  
  11.     //创建菜单  
  12.     @Override  
  13.     public boolean onCreateOptionsMenu(Menu menu)  
  14.     {  
  15.         // 建立菜单  
  16.         menu.add(0, menuSettings, 2"设置");  
  17.         return super.onCreateOptionsMenu(menu);  
  18.     }  
  19.     //菜单选择事件处理  
  20.     @Override  
  21.     public boolean onMenuItemSelected(int featureId, MenuItem item)  
  22.     {  
  23.         switch (item.getItemId())  
  24.         {  
  25.             case menuSettings:  
  26.                 //转到Settings设置界面  
  27.                 startActivityForResult(new Intent(this, Settings.class), REQ_SYSTEM_SETTINGS);  
  28.                 break;  
  29.             default:  
  30.                 break;  
  31.         }  
  32.         return super.onMenuItemSelected(featureId, item);  
  33.     }  
  34.     //Settings设置界面返回的结果  
  35.     protected  void onActivityResult(int requestCode, int resultCode, Intent data) {  
  36.         if(requestCode == REQ_SYSTEM_SETTINGS)  
  37.         {  
  38.             //获取设置界面PreferenceActivity中各个Preference的值  
  39.             String updateSwitchKey = getResources().getString(R.string.auto_update_switch_key);  
  40.             String updateFrequencyKey = getResources().getString(R.string.auto_update_frequency_key);  
  41.             //取得属于整个应用程序的SharedPreferences  
  42.             SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);  
  43.             Boolean updateSwitch = settings.getBoolean(updateSwitchKey, true);  
  44.             String updateFrequency = settings.getString(updateFrequencyKey, "10");  
  45.             //打印结果  
  46.             Log.v("CheckBoxPreference_Main", updateSwitch.toString());  
  47.             Log.v("ListPreference_Main", updateFrequency);  
  48.         }  
  49.         else  
  50.         {  
  51.             //其他Intent返回的结果  
  52.         }  
  53.     }  
  54. }

信息会自动存在以key值命名的map中,checkboxpreference就是boolean值,listpreference就是string。

大致就是这样。注意:SharedPreference仅适用于小数据的存取。