在Ap中有時需要設定一些配置參數,這些參數通過配置檔案儲存。
為了設定這些參數,需要提供一個UI,針對這種需求,Android提供了preferenceActivity。
PreferenceActivity通過讀取預先定義的xml檔案來生成界面,并能夠自動的根據使用者的操作來修改參數,并儲存到配置檔案中供讀取。
1.MainActivity:
按下Menu按鍵彈出菜單,點選菜單啟動SettingActivity。
2.SettingActivity繼承自PreferenceActivity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
在onCreate函數中加載參數定義檔案。
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key);
當參數值被改變時會調用此Listener,可以在此Listener中作一些界面重新整理工作,比如目前參數值改變為新的值。
Preference android.preference.PreferenceActivity.findPreference(CharSequence key);
擷取指定key所對應的preference對象,即使此key在配置檔案中尚未儲存,也能夠得到preference對象,而不會是null。
3.settings.xml:儲存在xml目中的參數定義檔案,在建立Android XML檔案時選擇Preference即可建立一個空的參數定義檔案。
xmlns:android="http://schemas.android.com/apk/res/android">
添加一個CheckBoxPreference子項,并設定屬性:
Key:checkbox_key
Title:CheckBox Item
Summary:test check box item
android:title="CheckBox Item" android:summary="test check box item">
key是用來通路此參數的值的關鍵字,儲存後的配置檔案類似如下内容:
啟動Ap,點選菜單,即可看到參數設定界面,并且當使用者點選操作改變了參數值後,也會被自動儲存。
4.使用參數值:
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
boolean check_test = sp.getBoolean("checkbox_key", false);
進階:
1.儲存參數檔案的路徑:
/data/data/包名/shared_prefs/包名_preferences.xml
如果想指定儲存檔案名,可使用:
getPreferenceManager().setSharedPreferencesName("配置檔案名");
2.其他的參數配置項:
2.1 EditTextPreference:
android:key="edittext_key" android:dialogMessage="Please Input text"
android:title="EditText Item" android:summary="test edittext item">
此參數設定項會彈出一個文本輸入對話框,并在配置檔案中生成類似以下内容:
this is a good text
彈出對話框的圖示、标題、提示資訊、Icon、以及兩個按鈕的文本都可以設定。
至于自定義對話框的布局,雖然有這個屬性,但是自定義布局後就不能自動儲存值了,
本來以為隻要放一個ID和原來一樣的EditText就能,但是檢視源代碼,發現其EditText是new出來的,沒法替代。
2.2 PreferenceCategory:一個分類分隔條。隻有title屬性有效。
2.3 PreferenceScreen:此項包含的所有子項在新螢幕上顯示,就好像進入二級菜單。
2.4 ListPreference:會彈出一個清單對話框供選擇。
2.5 RingtonePreference:會彈出系統鈴聲清單供選擇。
2.6 Preference:通用參數項。點選後需要程式自己響應事件。
3.自定義選項:
系統的提供的界面有時不能滿足需要,這時就需要自定義選項了。
有兩種方法可以實作自定義選項,一是用Preference作為選項,并重新實作onPreferenceTreeClick函數。
一是自定義一個類,類似于EditTextPreference這種系統内置的類,然後引用。
3.1使用一個Preference占位,然後重新實作onPreferenceTreeClick()函數:
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,Preference preference) {
String key = preference.getKey();
if( key != null ){
if(key.equals("some_key")) {
showDialog(DIALOG_SOME_KEY);
}
}
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
當點選指定key的Preference時,就會彈出對話框,然後在合适的時機使用如下代碼儲存參數即可。
SharedPreferences.Editor editor = preference.getEditor();
editor.putLong("ttt", 123);
editor.commit();
此種方法如果要觸發onSharedPreferenceChanged(),可以通過preference.getOnPreferenceChangeListener()擷取listener然後來呼叫。
3.2自定義選項類:
此處以一個選擇時間的對話框選項為例。
3.2.1 從DialogPreference繼承一個類:
public class TimePreference extends DialogPreference
3.2.2 構造函數:
public TimePreference(Context context, AttributeSet attrs) {
super(context, attrs);
setDialogLayoutResource(R.layout.time_preference);//加載布局檔案
}
3.3.3 布局檔案:
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
定義了一個id為timePicker_preference的TimePicker。
3.3.4 界面初始化:在dialog的函數中通過id找到TimePicker,然後使用已經存儲的值或者預設值,再設定到TimerPicker中。
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
mPicker = (TimePicker)view.findViewById(R.id.timePicker_preference);
if(mPicker != null) {
mPicker.setIs24HourView(true);
long value = mValue;
Date d = new Date(value);
mPicker.setCurrentHour(d.getHours());
mPicker.setCurrentMinute(d.getMinutes());
}
}
3.3.5 儲存值:在對話框關閉時儲存值。
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if(positiveResult) {
Date d = new Date(0, 0, 0, mPicker.getCurrentHour(), mPicker.getCurrentMinute(), 0);
long value = d.getTime();
if(callChangeListener(value)) {
setValue(value);
}
}
}
3.3.6 使用此preference:
在參數定義檔案中增加:
類似于使用自定義控件。
運作即可看到效果:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SYygzMjFTMmVjYjFzMwczYjRGNidTMxkzNjNTZzMDNm9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
3.3.7 使用預設值:
在參數定義檔案中增加一個定義:
并且自定的preference類中要實作兩個函數:
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getString(index);
}
以及
@Override
protected void onSetInitialValue(boolean restorePersistedValue,Object defaultValue) {
long value;
if(restorePersistedValue) value = getPersistedLong(0);
else {
value = Long.parseLong(defaultValue.toString());
}
setValue(value);
}
當PreferenceActivity啟動時會構造TimePreference,此時會調用onGetDefaultValue,然後調用onSetInitialValue,在onSetInitialValue儲存初始值,并在onBindDialogView中使用儲存的值進而可以使用預設值。