CheckBoxPreference--数据存储

最近,做一个项目,使用 Preference 非常频繁,之前就很想写一些关于 android 数据存储的文章,这次机会来了。


先从小出着手吧,CheckBoxPreference 小巧可爱,使用简单。但是使用的时候,还是需要注意一些问题。下面开始讨论吧,欢迎拍砖!


app 运行之后,效果(很单调):




项目结构图:




这里关键是在 res/ 目录下面新建 xml 文件夹,然后新建我们需要的 Preference 布局(demo.xml)。


demo.xml 文件:

[html]  view plain copy print ?
  1. xml version="1.0" encoding="utf-8"?>  
  2. <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:title="Demo for checkboxpreference" >  
  4.   
  5.     <CheckBoxPreference  
  6.         android:key="key_cbp"  
  7.         android:title="checkbox"   
  8.          android:summary="this is a demo"  
  9.         android:summaryOn="open me"  
  10.         android:summaryOff="close me"  
  11.         android:persistent="false"/>  
  12.   
  13. PreferenceScreen>  


代码部分,是一个继承自 PreferenceActivity 的类:

[java]  view plain copy print ?
  1. package mark.zhang;  
  2.   
  3. import android.os.Bundle;  
  4. import android.preference.CheckBoxPreference;  
  5. import android.preference.Preference;  
  6. import android.preference.PreferenceActivity;  
  7. import android.preference.Preference.OnPreferenceChangeListener;  
  8. import android.preference.Preference.OnPreferenceClickListener;  
  9. import android.util.Log;  
  10.   
  11. public class DemoActivity extends PreferenceActivity implements OnPreferenceClickListener,  
  12.         OnPreferenceChangeListener {  
  13.   
  14.     private static final String KEY = "key_cbp";  
  15.   
  16.     private CheckBoxPreference cbp = null;  
  17.   
  18.     @Override  
  19.     public void onCreate(Bundle savedInstanceState) {  
  20.         super.onCreate(savedInstanceState);  
  21.         addPreferencesFromResource(R.xml.demo);  
  22.   
  23.         cbp = (CheckBoxPreference) findPreference(KEY);  
  24.   
  25.         cbp.setOnPreferenceClickListener(this);  
  26.         cbp.setOnPreferenceChangeListener(this);  
  27.     }  
  28.   
  29.     @Override  
  30.     public boolean onPreferenceClick(Preference preference) {  
  31.         Log.d("mark""onPreferenceClick is invoked !");  
  32.         return false;  
  33.     }  
  34.   
  35.     @Override  
  36.     public boolean onPreferenceChange(Preference preference, Object newValue) {  
  37.         Log.d("mark""onPreferenceChange is invoked !");  
  38.         return false;  
  39.     }  
  40. }  


在这个类中,实现两个接口,接口方法会在点击该 CheckBoxPreference 时回调。


似乎,上面的内容没有什么很难的地方,的确!但是运行 App 之后,你会发现 CheckBox 不可以选择?!


在 API 的文档关于 onPreferenceChange 方法中有这么一句:

[html]  view plain copy print ?
  1. True to update the state of the Preference with the new value.  

可以看出,在这个方法的结尾返回 true 就可以了,呵呵!这点要注意,细节决定效率嘛!


ok,再看第二个问题,我们知道 Preference 可以自动保存状态值,保存是以 xml 文件形式保存的,保存路径在 /data/data/packageName/shared_prefs/×××.xml,但是你到这个路径去找找绝对找不到?!


原因在于我们所写的 demo.xml 文件,在这个文件中,有这么一句:

[html]  view plain copy print ?
  1. android:persistent="false"  

这就表示不会保存 CheckBoxPreference 这个值(是一个 boolean 值,选择上就是 true,否则就是false)了。


如果,你设置这个属性为 true,android 就会为你自动保存,看下图:



但是为什么会自动保存?为什么文件名称就是 mark.zhang_preference 呢?当然是代码决定的,看源码,就会一目了然了!


当我们点击 CheckBoxPreference 的时候,会触发事件:

[java]  view plain copy print ?
  1. protected void onClick() {  
  2.         super.onClick();  
  3.           
  4.         boolean newValue = !isChecked();  
  5.           
  6.         // in onBindView() an AccessibilityEventViewClickedType is sent to announce the change  
  7.         // not sending  
  8.         mSendAccessibilityEventViewClickedType = true;  
  9.   
  10.         if (!callChangeListener(newValue)) {  
  11.             return;  
  12.         }  
  13.           
  14.         setChecked(newValue);  
  15.     }  


那麽,

[java]  view plain copy print ?
  1. setChecked(newValue)  

方法就可以调用,

[java]  view plain copy print ?
  1. persistBoolean(checked);  

方法,该方法是 Preference 类的方法,然后调用 PreferenceManager 相关的方法获取 SharedPreference 来保存文件。


最后,看一个小问题,就是如何动态获取 CheckBoxPreerence 的值呢?很简单,实现 OnSharedPreferenceChangeListener 接口,看代码:

[java]  view plain copy print ?
  1. package mark.zhang;  
  2.   
  3. import android.content.SharedPreferences;  
  4. import android.content.SharedPreferences.OnSharedPreferenceChangeListener;  
  5. import android.os.Bundle;  
  6. import android.preference.CheckBoxPreference;  
  7. import android.preference.Preference;  
  8. import android.preference.PreferenceActivity;  
  9. import android.preference.Preference.OnPreferenceChangeListener;  
  10. import android.preference.Preference.OnPreferenceClickListener;  
  11. import android.util.Log;  
  12.   
  13. public class DemoActivity extends PreferenceActivity implements OnPreferenceClickListener,  
  14.         OnPreferenceChangeListener, OnSharedPreferenceChangeListener {  
  15.   
  16.     private static final String KEY = "key_cbp";  
  17.   
  18.     private CheckBoxPreference cbp = null;  
  19.   
  20.     @Override  
  21.     public void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         addPreferencesFromResource(R.xml.demo);  
  24.   
  25.         cbp = (CheckBoxPreference) findPreference(KEY);  
  26.   
  27.         cbp.setOnPreferenceClickListener(this);  
  28.   
  29.         // 注册OnPreferenceChangeListene  
  30.         // cbp.setOnPreferenceChangeListener(this);  
  31.   
  32.         // 注册 SharedPreferenceChangeListener  
  33.   
  34.         // 以便回调 onSharedPreferenceChangeListener  
  35.         getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);  
  36.   
  37.     }  
  38.   
  39.     @Override  
  40.     public boolean onPreferenceClick(Preference preference) {  
  41.         Log.d("mark""onPreferenceClick is invoked !");  
  42.   
  43.         if (cbp.isChecked()) { // false  
  44.             Log.d("mark""cbp.isChecked() = " + cbp.isChecked());  
  45.         }  
  46.         // return true;  
  47.         return false;  
  48.     }  
  49.   
  50.     @Override  
  51.     public boolean onPreferenceChange(Preference preference, Object newValue) {  
  52.         if (preference.getKey().equals(KEY)) {  
  53.             Log.d("mark""onPreferenceChange is invoked !" + newValue); // true  
  54.         }  
  55.   
  56.         // 不可以选择CheckBox  
  57.         // return false;  
  58.   
  59.         // 可以选择CheckBox  
  60.         return true;  
  61.     }  
  62.   
  63.     @Override  
  64.     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {  
  65.         if (key.equals(KEY)) {  
  66.             boolean value = sharedPreferences.getBoolean(key, false);  
  67.             Log.d("mark""onSharedPreferenceChanged is invoked !" + " and the value = " + value);  
  68.         }  
  69.     }  
  70.   
  71.     @Override  
  72.     protected void onDestroy() {  
  73.         // 注销 SharedPreferenceChangeListener  
  74.         getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(  
  75.                 this);  
  76.         super.onDestroy();  
  77.     }  
  78. }  


运行之后,可以看到如下打印信息:

[html]  view plain copy print ?
  1. D/mark    ( 8077): onSharedPreferenceChanged is invoked ! and the value = false  
  2. D/mark    ( 8077): onPreferenceClick is invoked !  
  3. D/mark    ( 8077): onSharedPreferenceChanged is invoked ! and the value = true  
  4. D/mark    ( 8077): onPreferenceClick is invoked !  
  5. D/mark    ( 8077): cbp.isChecked() = true  


提醒一点,如果不注册onSharedPreferenceChangListener:

[java]  view plain copy print ?
  1. getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);  


是不会回调 onSharedPreferenceChanged 方法的。




你可能感兴趣的:(android,android,数据存储)