https://blog.csdn.net/ichliebephone/article/details/5916320
今天在做一个设置界面的时候,我陷入了长思,到底如何才能把设置界面做的好看呢。于是我在网络的海洋中,发现了preferences,现在来开始学习他。
一、
Preferences是一个自带数据持久化功能的东西
二、
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后就可以对数据进行读取或者保存了。
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.xml的File文件,内容如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="Settings">
- <CheckBoxPreference
- android:title="Love me?"
- android:summaryOn="Yes,I love you!"
- android:summaryOff="No,I am sorry."
- android:defaultValue="true">
- </CheckBoxPreference>
- </PreferenceScreen>
或者
- <?xml version="1.0" encoding="UTF-8"?>
- <PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="Settings">
- <PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="Emotions"
- android:summary="settings about emotions">
- <CheckBoxPreference
- android:title="Love me?"
- android:summaryOn="Yes,I love you!"
- android:summaryOff="No,I am sorry."
- android:defaultValue="true">
- </CheckBoxPreference>
- <CheckBoxPreference
- android:title="Hate me?"
- android:summaryOn="Yes,I hate you!"
- android:summaryOff="No,you are a good person."
- android:defaultValue="false">
- </CheckBoxPreference>
- </PreferenceScreen>
- <PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="Relations"
- android:summary="settings about relations">
- <CheckBoxPreference
- android:title="Family?"
- android:summaryOn="Yes,we are family!"
- android:summaryOff="No,I am sorry."
- android:defaultValue="true">
- </CheckBoxPreference>
- <CheckBoxPreference
- android:title="Friends?"
- android:summaryOn="Yes,we are friends!"
- android:summaryOff="No,I am sorry."
- android:defaultValue="false">
- </CheckBoxPreference>
- </PreferenceScreen>
- </PreferenceScreen>
在上面的xml中,出现了和管理布局显示相关的除了PreferenceScreen外,还有一个常用的为PreferenceCategory,我们把上面xml文件中间那两个PreferenceScreen改为PreferenceCategory就可以看到PreferenceCategory的显示效果了。
接下来说一下ListPreferences的用法:
首先在res/values/文件夹下新建一个取名为array.xml的文件,内容为:
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <!-- 系统设置界面需要要到的数组 -->
- <string-array name="auto_update_frequency_entry">
- <item>10分钟</item>
- <item>30分钟</item>
- <item>1小时</item>
- <item>12小时</item>
- <item>24小时</item>
- </string-array>
- <string-array name="auto_update_frequency_value">
- <item>10</item>
- <item>30</item>
- <item>60</item>
- <item>720</item>
- <item>1440</item>
- </string-array>
- </resources>
然后在res/values/strings.xml文件中添加:
- <!-- 统设置界面需要要到的字符串 -->
- <string name="system_settings">系统设置</string>
- <string name="auto_update_setting">自动更新设置</string>
- <string name="auto_update_switch_title">自动更新</string>
- <string name="auto_update_switch_key">auto_update_switch</string>
- <string name="auto_update_switch_summary_on">开启自动更新</string>
- <string name="auto_update_switch_summary_off">关闭自动更新</string>
- <string name="auto_update_frequency_title">更新频率</string>
- <string name="auto_update_frequency_key">auto_update_frequency</string>
- <string name="auto_update_frequency_default_value">10</string>
- <string name="auto_update_frequency_summary">设置自动更新的时间周期</string>
- <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还提供了OnPreferenceClickListener和OnPreferenceChangeListener两个与Preference相关的监听接口,当PreferenceActivity中的某一个Preference进行了点击或者改变的操作时,都会回调接口中的函数,这样可以第一个时间向其他Activity等通知系统设置进行了改变。
下面我们以一个具体的Demo说明PreferenceActivity和其监听接口的使用。
新建一个工程AndroidPreferenceDemoII,并按上面的步骤添加xml文件夹和其内容Preferenceii.xml,还有values文件夹中的array.xml和strings.xml。
新建一个名为Settings的class,内容为:
- //继承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;
- }
- }
其中change方法时在设置有改变的时候才会出发,click就是点击的时候会触发,要注意。
- public class AndroidPreferenceDemoII extends Activity {
- /** Called when the activity is first created. */
- // 菜单项
- final private int menuSettings=Menu.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返回的结果
- }
- }
- }
信息会自动存在以key值命名的map中,checkboxpreference就是boolean值,listpreference就是string。
大致就是这样。注意:SharedPreference仅适用于小数据的存取。