如果你想在app 中加入Setting 的功能讓使用者可以修改app 的功能和行為, 甚至將Setting value同步到 System Setting , Preference APIs 是一個不錯的選擇, 它的UI呈現方式就像 ListView 一樣, 而每個在ListView 中的subView 都可以宣告一個Key 為的是可以在SharedPreference 中存取資料, 如此一來Preference API 就會自動的幫我們儲存每個subView資料的變化, 讓我們省了不少功夫。
首先第一步要做的就是定義 XML, 將Setting 中會出現的各種Preference object 使用階層式的方式在XML 中定義清楚, 我們在 res/xml 中產生一個 XML 檔案preference.xml 如下:
在XML 檔案中 root element 必定為 PreferenceScreen, 代表著一個全新的Setting 畫面並且在其中加入我們所需要的Preference objects, 通常我們只會用到一個XML 檔案, 因為如果有需要新的Setting 畫面需求, 可以在root PreferenceScreen 中加入另一個PreferenceScreen 形成巢狀Setting。
我們使用Eclipse editor 的 Structure mode來編輯preference.xml, 這樣對於preference.xml 階層式的架構就非常清楚了, 所有的 Preference objects 都在root Preference中, 另外還加入了一個Second PreferenceScreen, 當使用者點選時會跳出一個新的Setting 畫面, 無需create 一個額外activity。
接下來介紹幾個常用的 attribute:
android:key
android:title
android:defaultValue
SharedPreference 中儲存的初始值
android:summary
Preference object 出現在Setting 畫面中的說明文字, 以較小的字出現在title 下方。
接下來先附上完整的 preference.xml, 再來針對每個Preference object 作介紹
EditTextPreference : 當使用者選擇時會跳出Dialog, 而關於這個Dialog 的屬性可以使用 Editor 事先編輯, 特別的是EditText 能宣告的屬性, EditTextPreference 也能拿來使用, 所以在這邊宣告了 inputType 屬性為只能輸入Decimal number, 另外我們將使用者輸入的數字顯示在summay 中, 不過這邊需要在PreferenceActivity 中加入此功能, 這部分稍後會提到。
ListPreference : 顯示一組有著Radio button 的List, 要使List 能呈現內容的話, 要事先為List import Entry array和Entry value array, 我們可以在 /res/value 中宣告 string array 再使用Editor 引入即可, array 內容如下:
PreferenceActivity Hello world! Settings MainActivity - First item
- Second item
- Third item
- 0
- 1
- 2
Entry 宣告了要顯示在List 中的內容, Entry value 對應為每個 Entry 內容所代表的value
另外值得一提的是因為選擇ListPrefence時會跳出Dialog 所以如果在Editor 中再宣告Dialog Message 屬性時就會導致顯示內容錯誤, 另外Dialog 只會出現Negative Button !
RingtonePreference : 讓使用者選擇手機上的鈴聲, 將被選擇鈴聲的URI 以string 格式儲存在SharedPreference 中, showSilent 屬性表示列表中是否包含靜音的選項, ringtoneType 用來限制列表中顯示的鈴聲類型。
PreferenceCategory : 單純的將Prefence object 分類而已, 在針對不同的Category 內加入Preference object, 可以看到畫面上的"第一個分類", "第二個分類"....均是。
Preference : 更單純, 通常只是被用來當作"說明"功能而已。
稍微簡介了用到的Preference Objects 之後, 開始來看PreferenceActivity.java 程式主要在處理每個Preference object 初始的Summary 設定, 和註冊value change 的事件。
package com.example.preferenceactivity; import android.os.Bundle; import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.PreferenceScreen; import android.preference.RingtonePreference; import android.view.Menu; public class MainActivity extends PreferenceActivity implements OnPreferenceChangeListener { EditTextPreference editTextPreference, secondEditTextPreference; ListPreference listPreference; RingtonePreference ringtonePreference; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preference); // 記得替換掉預設的 setContentView(R.layout.activity_main) editTextPreference = (EditTextPreference) findPreference("EditTextP"); editTextPreference.setOnPreferenceChangeListener(this); //替Preference註冊value改變事件, 因為我們要動態的更新Summary content editTextPreference.setSummary("EditTextPreference Value:" +editTextPreference.getText()); listPreference = (ListPreference) findPreference("ListP"); listPreference.setOnPreferenceChangeListener(this); listPreference.setSummary("ListPreference Value:"+ listPreference.getEntry()); ringtonePreference = (RingtonePreference) findPreference("RingtoneP"); ringtonePreference.setOnPreferenceChangeListener(this); //---In the second Screen secondEditTextPreference = (EditTextPreference) findPreference("SPCEditTextP"); secondEditTextPreference.setOnPreferenceChangeListener(this); secondEditTextPreference.setSummary("EditTextPreference Value:" +secondEditTextPreference.getText()); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } @Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { // TODO Auto-generated method stub return super.onPreferenceTreeClick(preferenceScreen, preference); } public boolean onPreferenceChange(Preference preference, Object newValue) { // TODO Auto-generated method stub if(preference.getKey().equals("EditTextP")) //根據不同的key來辨別不同的Preference preference.setSummary("EditTextPreference Value:" +newValue); else if(preference.getKey().equals("ListP")) preference.setSummary("ListPreference Value:" +((ListPreference) preference).getEntries()[Integer.parseInt(newValue.toString())]); //從Entry中對應顯示使用者選擇的item value else if(preference.getKey().equals("RingtoneP")) preference.setSummary("RingtonePreference Value:" +newValue); else if(preference.getKey().equals("SPCEditTextP")) preference.setSummary("EditTextPreference Value:" +newValue); return true; } }
最後當我們成功儲存了每個Preference objects value 後, 該透過甚麼方法取得呢?
網路上建議的作法:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return value preferences 為 context 所使用的preference file, 接下來就可以對 preferences 進行數值的存取了。
相關文章:
nice!!實用
回覆刪除原來要先選告需要註冊Listener的物件
再指派Listener給物件
Shung007'S Secret Base: [Android] 如何使用 Preferenceactivity 及宣告preference.Xml (How To Use Preferenceactivity And Define Preference.Xml) >>>>> Download Now
回覆刪除>>>>> Download Full
Shung007'S Secret Base: [Android] 如何使用 Preferenceactivity 及宣告preference.Xml (How To Use Preferenceactivity And Define Preference.Xml) >>>>> Download LINK
>>>>> Download Now
Shung007'S Secret Base: [Android] 如何使用 Preferenceactivity 及宣告preference.Xml (How To Use Preferenceactivity And Define Preference.Xml) >>>>> Download Full
>>>>> Download LINK