資料存放區: CheckBoxPreference

來源:互聯網
上載者:User

最近,做一個項目,使用 Preference 非常頻繁,之前就很想寫一些關於 android 資料存放區的文章,這次機會來了。


先從小出著手吧,CheckBoxPreference 小巧可愛,使用簡單。但是使用的時候,還是需要注意一些問題。下面開始討論吧,歡迎拍磚!


app 運行之後,效果(很單調):




項目結構圖:




這裡關鍵是在 res/ 目錄下面建立 xml 檔案夾,然後建立我們需要的 Preference 布局(demo.xml)。


demo.xml 檔案:

<?xml version="1.0" encoding="utf-8"?><PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"    android:title="Demo for checkboxpreference" >    <CheckBoxPreference        android:key="key_cbp"        android:title="checkbox"          android:summary="this is a demo"        android:summaryOn="open me"        android:summaryOff="close me"        android:persistent="false"/></PreferenceScreen>


代碼部分,是一個繼承自 PreferenceActivity 的類:

package mark.zhang;import android.os.Bundle;import android.preference.CheckBoxPreference;import android.preference.Preference;import android.preference.PreferenceActivity;import android.preference.Preference.OnPreferenceChangeListener;import android.preference.Preference.OnPreferenceClickListener;import android.util.Log;public class DemoActivity extends PreferenceActivity implements OnPreferenceClickListener,        OnPreferenceChangeListener {    private static final String KEY = "key_cbp";    private CheckBoxPreference cbp = null;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        addPreferencesFromResource(R.xml.demo);        cbp = (CheckBoxPreference) findPreference(KEY);        cbp.setOnPreferenceClickListener(this);        cbp.setOnPreferenceChangeListener(this);    }    @Override    public boolean onPreferenceClick(Preference preference) {        Log.d("mark", "onPreferenceClick is invoked !");        return false;    }    @Override    public boolean onPreferenceChange(Preference preference, Object newValue) {        Log.d("mark", "onPreferenceChange is invoked !");        return false;    }}


在這個類中,實現兩個介面,介面方法會在點擊該 CheckBoxPreference 時回調。


似乎,上面的內容沒有什麼很難的地方,的確!但是運行 App 之後,你會發現 CheckBox 不可以選擇?!


在 API 的文檔關於 onPreferenceChange 方法中有這麼一句:

True to update the state of the Preference with the new value.

可以看出,在這個方法的結尾返回 true 就可以了,呵呵!這點要注意,細節決定效率嘛!


ok,再看第二個問題,我們知道 Preference 可以自動儲存狀態值,儲存是以 xml 檔案形式儲存的,儲存路徑在 /data/data/packageName/shared_prefs/×××.xml,但是你到這個路徑去找找絕對找不到?!


原因在於我們所寫的 demo.xml 檔案,在這個檔案中,有這麼一句:

android:persistent="false"

這就表示不會儲存 CheckBoxPreference 這個值(是一個 boolean 值,選擇上就是 true,否則就是false)了。


如果,你設定這個屬性為 true,android 就會為你自動儲存,看:



但是為什麼會自動儲存?為什麼檔案名稱就是 mark.zhang_preference 呢?當然是代碼決定的,看源碼,就會一目瞭然了!


當我們點擊 CheckBoxPreference 的時候,會觸發事件:

protected void onClick() {        super.onClick();                boolean newValue = !isChecked();                // in onBindView() an AccessibilityEventViewClickedType is sent to announce the change        // not sending        mSendAccessibilityEventViewClickedType = true;        if (!callChangeListener(newValue)) {            return;        }                setChecked(newValue);    }


那麽,

 setChecked(newValue)

方法就可以調用,

persistBoolean(checked);

方法,該方法是 Preference 類的方法,然後調用 PreferenceManager 相關的方法擷取 SharedPreference 來儲存檔案。


最後,看一個小問題,就是如何動態擷取 CheckBoxPreerence 的值呢?很簡單,實現 OnSharedPreferenceChangeListener 介面,看代碼:

package mark.zhang;import android.content.SharedPreferences;import android.content.SharedPreferences.OnSharedPreferenceChangeListener;import android.os.Bundle;import android.preference.CheckBoxPreference;import android.preference.Preference;import android.preference.PreferenceActivity;import android.preference.Preference.OnPreferenceChangeListener;import android.preference.Preference.OnPreferenceClickListener;import android.util.Log;public class DemoActivity extends PreferenceActivity implements OnPreferenceClickListener,        OnPreferenceChangeListener, OnSharedPreferenceChangeListener {    private static final String KEY = "key_cbp";    private CheckBoxPreference cbp = null;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        addPreferencesFromResource(R.xml.demo);        cbp = (CheckBoxPreference) findPreference(KEY);        cbp.setOnPreferenceClickListener(this);        // 註冊OnPreferenceChangeListene        // cbp.setOnPreferenceChangeListener(this);        // 註冊 SharedPreferenceChangeListener        // 以便回調 onSharedPreferenceChangeListener        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);    }    @Override    public boolean onPreferenceClick(Preference preference) {        Log.d("mark", "onPreferenceClick is invoked !");        if (cbp.isChecked()) { // false            Log.d("mark", "cbp.isChecked() = " + cbp.isChecked());        }        // return true;        return false;    }    @Override    public boolean onPreferenceChange(Preference preference, Object newValue) {        if (preference.getKey().equals(KEY)) {            Log.d("mark", "onPreferenceChange is invoked !" + newValue); // true        }        // 不可以選擇CheckBox        // return false;        // 可以選擇CheckBox        return true;    }    @Override    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {        if (key.equals(KEY)) {            boolean value = sharedPreferences.getBoolean(key, false);            Log.d("mark", "onSharedPreferenceChanged is invoked !" + " and the value = " + value);        }    }    @Override    protected void onDestroy() {        // 登出 SharedPreferenceChangeListener        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(                this);        super.onDestroy();    }}


運行之後,可以看到如下列印資訊:

D/mark    ( 8077): onSharedPreferenceChanged is invoked ! and the value = falseD/mark    ( 8077): onPreferenceClick is invoked !D/mark    ( 8077): onSharedPreferenceChanged is invoked ! and the value = trueD/mark    ( 8077): onPreferenceClick is invoked !D/mark    ( 8077): cbp.isChecked() = true


提醒一點,如果不註冊onSharedPreferenceChangListener:

getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);


是不會回調 onSharedPreferenceChanged 方法的。







聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.