Android PreferenceActivity 學習筆記

 在Ap中有時需要設置一些配置參數,這些參數通過配置文件保存。

爲了設置這些參數,需要提供一個UI,針對這種需求,Android提供了preferenceActivity。
PreferenceActivity通過讀取預先定義的xml文件來生成界面,並能夠自動的根據用戶的操作來修改參數,並保存到配置文件中供讀取。
1.MainActivity:
按下Menu按鍵彈出菜單,點擊菜單啓動SettingActivity。
2.SettingActivity繼承自PreferenceActivity:

Java代碼
  1. @Override  
  2.     protected void onCreate(Bundle savedInstanceState) {  
  3.         super.onCreate(savedInstanceState);  
  4.         addPreferencesFromResource(R.xml.settings);  
  5.     }  

 

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		addPreferencesFromResource(R.xml.settings);
	}

在onCreate函數中加載參數定義文件。

Java代碼
  1. public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key);  

 

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key);

 

 

當參數值被改變時會調用此Listener,可以在此Listener中作一些界面刷新工作,比如當前參數值改變爲新的值。

 

Java代碼
  1. Preference android.preference.PreferenceActivity.findPreference(CharSequence key);  

 

Preference android.preference.PreferenceActivity.findPreference(CharSequence key);

 

 

獲取指定key所對應的preference對象,即使此key在配置文件中尚未保存,也能夠得到preference對象,而不會是null。

 

 

3.settings.xml:保存在xml目中的參數定義文件,在創建Android XML文件時選擇Preference即可創建一個空的參數定義文件。

 

Xml代碼
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.     <PreferenceScreen  
  3.         xmlns:android="http://schemas.android.com/apk/res/android">  
  4.     </PreferenceScreen>  

 

<?xml version="1.0" encoding="utf-8"?>
	<PreferenceScreen
 		xmlns:android="http://schemas.android.com/apk/res/android">
	</PreferenceScreen>

 

 

添加一個CheckBoxPreference子項,並設置屬性:

Key:checkbox_key

 

Title:CheckBox Item

Summary:test check box item

Xml代碼
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.     <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <CheckBoxPreference android:key="checkbox_key"  
  4.         android:title="CheckBox Item" android:summary="test check box item"></CheckBoxPreference>  
  5.     </PreferenceScreen>  

 

<?xml version="1.0" encoding="utf-8"?>
	<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
	<CheckBoxPreference android:key="checkbox_key"
		android:title="CheckBox Item" android:summary="test check box item"></CheckBoxPreference>
	</PreferenceScreen>

 

 

key是用來訪問此參數的值的關鍵字,保存後的配置文件類似如下內容:

Xml代碼
  1. <?xml version='1.0' encoding='utf-8' standalone='yes' ?>  
  2.     <map>  
  3.         <boolean name="checkbox_key" value="true" />  
  4.     </map>  

 

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
	<map>
		<boolean name="checkbox_key" value="true" />
	</map>

啓動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:

Xml代碼
  1. <EditTextPreference android:dialogTitle="Edit Text Dialog"  
  2.         android:key="edittext_key" android:dialogMessage="Please Input text"  
  3.         android:title="EditText Item" android:summary="test edittext item"></EditTextPreference>  

 

<EditTextPreference android:dialogTitle="Edit Text Dialog"
		android:key="edittext_key" android:dialogMessage="Please Input text"
		android:title="EditText Item" android:summary="test edittext item"></EditTextPreference>

 

 

此參數設置項會彈出一個文本輸入對話框,並在配置文件中生成類似以下內容:

<string name="edittext_key">this is a good text</string>

 

彈出對話框的圖標、標題、提示信息、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()函數:

Java代碼
  1. public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {  
  2.         String key = preference.getKey();  
  3.         if( key != null ){  
  4.             if(key.equals("some_key")) {  
  5.                 showDialog(DIALOG_SOME_KEY);  
  6.             }  
  7.         }  
  8.         return super.onPreferenceTreeClick(preferenceScreen, preference);  
  9.     }  

 

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時,就會彈出對話框,然後在合適的時機使用如下代碼保存參數即可。

Java代碼
  1. SharedPreferences.Editor editor = preference.getEditor();  
  2.     editor.putLong("ttt", 123);  
  3.     editor.commit();  

 

SharedPreferences.Editor editor = preference.getEditor(); editor.putLong("ttt", 123); editor.commit();

 

此種方法如果要觸發onSharedPreferenceChanged(),可以通過preference.getOnPreferenceChangeListener()獲取listener然後來呼叫。

3.2自定義選項類:

 

此處以一個選擇時間的對話框選項爲例。

3.2.1 從DialogPreference繼承一個類:

Java代碼
  1. public class TimePreference extends DialogPreference  

 

public class TimePreference extends DialogPreference

3.2.2 構造函數:

Java代碼
  1. public TimePreference(Context context, AttributeSet attrs) {  
  2.         super(context, attrs);        
  3.         setDialogLayoutResource(R.layout.time_preference);  //加載佈局文件  
  4.     }  

 

public TimePreference(Context context, AttributeSet attrs) {
		super(context, attrs);		
		setDialogLayoutResource(R.layout.time_preference);	//加載佈局文件
	}

3.3.3 佈局文件:

Xml代碼
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.     <RelativeLayout  
  3.       xmlns:android="http://schemas.android.com/apk/res/android"  
  4.       android:layout_width="fill_parent"  
  5.       android:layout_height="fill_parent">  
  6.     <TimePicker android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/timePicker_preference" android:layout_centerHorizontal="true"></TimePicker>  
  7.     </RelativeLayout>  

 

<?xml version="1.0" encoding="utf-8"?>
	<RelativeLayout
	  xmlns:android="http://schemas.android.com/apk/res/android"
	  android:layout_width="fill_parent"
	  android:layout_height="fill_parent">
	<TimePicker android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/timePicker_preference" android:layout_centerHorizontal="true"></TimePicker>
	</RelativeLayout>

定義了一個id爲timePicker_preference的TimePicker。

 

3.3.4 界面初始化:在dialog的函數中通過id找到TimePicker,然後使用已經存儲的值或者默認值,再設置到TimerPicker中。

Java代碼
  1. @Override  
  2.     protected void onBindDialogView(View view) {  
  3.         super.onBindDialogView(view);  
  4.                   
  5.         mPicker = (TimePicker)view.findViewById(R.id.timePicker_preference);  
  6.         if(mPicker != null) {             
  7.             mPicker.setIs24HourView(true);  
  8.             long value = mValue;  
  9.             Date d = new Date(value);  
  10.             mPicker.setCurrentHour(d.getHours());  
  11.             mPicker.setCurrentMinute(d.getMinutes());  
  12.         }  
  13.           
  14.     }  

 

@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 保存值:在對話框關閉時保存值。

Java代碼
  1. @Override  
  2.     protected void onDialogClosed(boolean positiveResult) {  
  3.         super.onDialogClosed(positiveResult);  
  4.         if(positiveResult) {                  
  5.             Date d = new Date(0, 0, 0, mPicker.getCurrentHour(), mPicker.getCurrentMinute(), 0);              
  6.             long value = d.getTime();  
  7.             if(callChangeListener(value)) {  
  8.                 setValue(value);  
  9.             }  
  10.         }  
  11.     }  

 

@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:

 

在參數定義文件中增加:

Xml代碼
  1. <cn.demo.pa.TimePreference android:key="time_test" android:title="Test time preference"/>  

 

<cn.demo.pa.TimePreference android:key="time_test" android:title="Test time preference"/>

 

類似於使用自定義控件。

 

運行即可看到效果:

 

3.3.7 使用默認值:

 

在參數定義文件中增加一個定義:

Xml代碼
  1. <cn.demo.pa.TimePreference android:key="time_test" android:title="Test time preference" android:defaultValue="1000000"/>  

 

<cn.demo.pa.TimePreference android:key="time_test" android:title="Test time preference" android:defaultValue="1000000"/>

 

並且自定的preference類中要實現兩個函數:

Java代碼
  1. @Override  
  2. protected Object onGetDefaultValue(TypedArray a, int index) {  
  3.     return a.getString(index);  
  4. }  

 

@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
	return a.getString(index);
}

 

以及

Java代碼
  1. @Override  
  2.     protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {  
  3.         long value;  
  4.         if(restorePersistedValue) value = getPersistedLong(0);  
  5.         else {  
  6.             value = Long.parseLong(defaultValue.toString());  
  7.         }  
  8.         setValue(value);  
  9.     }  

 

@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中使用保存的值從而可以使 用默認值。

 http://blog.163.com/guozioo@126/blog/static/6408694720106711453584/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章