一、PreferenceFragment的引入:
PreferenceActivity是一個非常有用的基類,當我們開發Android項目時避免不了選項設置,這些設置習慣用Preference來保存。Android專門爲這種Activity提供了便捷的基類PreferenceActivity。如果繼承自Preference則不需要自己控制Preference的讀寫,PreferenceActivity會爲我們處理一切。
PreferenceActivity與普通的Activity不同,它不是使用界面佈局文件,而是使用選項設置的佈局文件。
選項設置佈局文件以PreferenceScreen作爲根元素來表示定義一個參數設置界面佈局。
從Android 3.0以後官方不再推薦直接讓PreferenceActivity加載選項設置佈局文件,而是建議使用PreferenceFragment,二者用法類似。所以今天就來學習一下。
下面的這張截圖就是一個典型的例子:
我們會看到整個頁面被分爲幾組:無線和網絡、個人、賬戶、設備、系統。這個分組(或者叫分類)就是PreferenceCategory。
Wifi右邊有開關,這一項就是CheckBoxPreference;其他還有ListPreference和EditTextPreference。
你的每一次設置,都會被Preference自動保存下來,這就是setting的數據持久化。每個Preference都是以鍵值對的形式保存下來的。
PreferenceActivity的繼承關係圖:(不推薦使用)
PreferenceFragment的繼承關係圖:(推薦使用)
二、在XML文件中Preference的種類:
根節點中一定是<PreferenceScreen> 元素,在這個元素中可以添加不同的Preference。常見的Preference控件有:
直接子類:DialogPreference, PreferenceGroup, RingtonePreference, TwoStatePreference 非直接子類:CheckBoxPreference, EditTextPreference, ListPreference, MultiSelectListPreference, PreferenceCategory, PreferenceScreen, SwitchPreference我們還是通過實際的例子來實現吧。
【實例】
先新建一個工程文件:
新建類PrefFragment.java,讓其繼承PreferenceFragment,並加載選項設置的佈局文件:(核心代碼是第6行和13行)
01.
1
package
com.example.m05_preffragment01;
02.
2
03.
3
import
android.os.Bundle;
04.
4
import
android.preference.PreferenceFragment;
05.
5
06.
<strong>
6
public
class
PrefFragment
extends
PreferenceFragment
{
07.
</strong>
7
@Override
08.
8
public
void
onCreate(Bundle
savedInstanceState) {
09.
9
//
TODO Auto-generated method stub
10.
10
super
.onCreate(savedInstanceState);
11.
11
12.
<strong>
12
//從xml文件加載選項
13.
13
addPreferencesFromResource(R.xml.preferences);
14.
</strong>
14
}
15.
15
}
然後,在MainActivity.java中加載上面的Fragment:
01.
1
package
com.example.m05_preffragment01;
02.
2
03.
3
import
android.app.Activity;
04.
4
import
android.app.FragmentManager;
05.
5
import
android.app.FragmentTransaction;
06.
6
import
android.os.Bundle;
07.
7
08.
8
public
class
MainActivity
extends
Activity
{
09.
9
10.
10
@Override
11.
11
protected
void
onCreate(Bundle
savedInstanceState) {
12.
12
super
.onCreate(savedInstanceState);
13.
13
setContentView(R.layout.activity_main);
14.
14
15.
15
//加載PrefFragment
16.
16
FragmentManager
fragmentManager = getFragmentManager();
17.
17
FragmentTransaction
transaction = fragmentManager.beginTransaction();
18.
18
PrefFragment
prefFragment =
new
PrefFragment();
19.
19
transaction.add(R.id.prefFragment,
prefFragment);
20.
20
transaction.commit();
21.
21
22.
22
}
23.
23
24.
24
}
接下來的知識就是重頭戲了,既然PrefFragment要加載選項設置的佈局文件R.xml.preferences,那我們就來定義一下這個preferences.xml:
在res目錄下新建立一個xml目錄,在該目錄中新建文件preferences.xml:
關於preferences.xml的文件裏面的代碼,請看下面這一段。
五、preference詳解:
1、<PreferenceCategory>的方式進行分組:
preferences.xml舉例如下:
01.
<?xml
version=
'1.0'
encoding=
'utf-8'
?>
02.
<PreferenceScreen
xmlns:android=
'http://schemas.android.com/apk/res/android'
>
03.
04.
<!--
設置的類別 -->
05.
<PreferenceCategory
06.
android:key=
'mylocation'
07.
android:summary=
'我的位置'
08.
android:title=
'我的位置源'
>
09.
<CheckBoxPreference
10.
android:key=
'wireless_network'
11.
android:summary=
'使用<a
href="http://www.it165.net/network/nwwx/" target="_blank"
class="keylink">無線網絡</a>查看應用程序中的位置'
12.
android:title=
'使用<a
href="http://www.it165.net/network/nwwx/" target="_blank"
class="keylink">無線網絡</a>'
/>
13.
</PreferenceCategory>
14.
15.
<PreferenceCategory
16.
android:key=
'mymsg'
17.
android:summary=
'個人信息'
18.
android:title=
'個人信息'
>
19.
<EditTextPreference
20.
android:key=
'myname'
21.
android:title=
'請輸入真實姓名'
22.
android:summary=
'姓名'
/>
23.
</PreferenceCategory>
24.
25.
</PreferenceScreen>
上方代碼中,一個<PreferenceCategory>就是一個類別,單個的<PreferenceCategory>可以放入任意的Preference控件。我們在第一個類別中放入了CheckBoxPreference控件,在第二個類別中放入了EditTextPreference控件。運行效果如下:
運行時候,會自動在/data/data/<packagename>/shared_prefs/目錄生成一個文本文件:
注:這個文本的文件名太長了,我們可以在上方PrefFragment.java的第13行代碼後面加上這樣一句話來修改文件名:(這裏我將文件名修改爲:mysetting)
1.
getPreferenceManager().setSharedPreferencesName(
'mysetting'
);
文本內容如下:
我們現在在CheckBoxPreference中打鉤,然後在EditTextPreference中輸入內容:
文本內容顯示如下:
2、顯示子屏幕subscreens方式的進行分組:
01.
1
<?xml
version=
'1.0'
encoding=
'UTF-8'
?>
02.
2
<PreferenceScreen
xmlns:android=
'http://schemas.android.com/apk/res/android'
03.
3
android:title=
'Settings'
>
04.
4
05.
5
<PreferenceScreen
06.
6
xmlns:android=
'http://schemas.android.com/apk/res/android'
07.
7
android:summary=
'settings
about emotions'
08.
8
android:title=
'Emotions'
>
09.
9
<CheckBoxPreference
10.
10
android:defaultValue=
'true'
11.
11
android:summaryOff=
'No,I
am sorry.'
12.
12
android:summaryOn=
'Yes,I
love you!'
13.
13
android:title=
'Love
me?'
>
14.
14
</CheckBoxPreference>
15.
15
<CheckBoxPreference
16.
16
android:defaultValue=
'false'
17.
17
android:summaryOff=
'No,you
are a good person.'
18.
18
android:summaryOn=
'Yes,I
hate you!'
19.
19
android:title=
'Hate
me?'
>
20.
20
</CheckBoxPreference>
21.
21
</PreferenceScreen>
22.
22
23.
23
<PreferenceScreen
24.
24
xmlns:android=
'http://schemas.android.com/apk/res/android'
25.
25
android:summary=
'settings
about relations'
26.
26
android:title=
'Relations'
>
27.
27
<CheckBoxPreference
28.
28
android:defaultValue=
'true'
29.
29
android:summaryOff=
'No,I
am sorry.'
30.
30
android:summaryOn=
'Yes,we
are family!'
31.
31
android:title=
'Family?'
>
32.
32
</CheckBoxPreference>
33.
33
<CheckBoxPreference
34.
34
android:defaultValue=
'false'
35.
35
android:summaryOff=
'No,I
am sorry.'
36.
36
android:summaryOn=
'Yes,we
are friends!'
37.
37
android:title=
'Friends?'
>
38.
38
</CheckBoxPreference>
39.
39
</PreferenceScreen>
40.
40
41.
41
</PreferenceScreen>
運行效果如下:
點擊上方第一個preference,進入下圖中左側界面;點擊上方第二個preference,進入下圖中右側界面。效果如下:
3、ListPreference控件:
點擊該控件後,將列出一個單選按鈕的列表。用法如下:
01.
<?xml
version=
'1.0'
encoding=
'utf-8'
?>
02.
<PreferenceScreen
xmlns:android=
'http://schemas.android.com/apk/res/android'
>
03.
04.
<PreferenceCategory
05.
android:key=
'mylocation'
06.
android:summary=
'我的位置'
07.
android:title=
'我的位置源'
>
08.
<ListPreference
09.
android:key=
'mycities'
10.
android:title=
'所屬城市'
11.
android:summary=
'點擊彈出城市列表'
12.
android:dialogTitle=
'請選擇城市'
13.
android:entries=
'@array/cities'
14.
android:entryValues=
'@array/cities'
/>
15.
</PreferenceCategory>
16.
17.
</PreferenceScreen>
上方代碼中,PreferenceScreen爲根標籤,ListPreference爲子標籤。ListPreference的常見屬性如下:
android:key 唯一標識符,和android:id相類似,PreferenceManager可以以其爲參數通過findPreference獲取指定的preference 。 注意,這個android:key的值也是Preference文件裏面的XML“鍵”名 android:title 大標題 android:summary 標題下面的小字(這個要作爲選項卡纔有) android:entries 彈出的對話框中,列表顯示的文本內容,注意哦,這裏指定的是一個數組。 android:entryValues 與android:entries相對應的值 android:defaultValue 當對應值不存在時的默認值 android:dialogTitle 彈出的對話框中的標題信息關於android:entries和android:entryValues的區別,要強調一下:
android:entries:The human-readable array to present as a list. 是展現給用戶的列表的值。 android:entryValues :he array to find the value to save for a preference when an entry from entries is selected. 展現的用戶的選擇列表的每個元素選擇後,需要存儲到手機中,這裏的entryValues就是列表中各個元素被選擇後存儲到手機中的值(通過sharedPreferences保存在/data/data/<packagename>/shared_prefs/目錄下)。簡單的說就是此處是數據庫中的值。上面的android:entries是展現給用戶的列表的值。我們在上方代碼中的第13、14行引用了數據,緊接着我們要在values目錄下的strings.xml文件中定義這個被引用的城市列表(即數據來源):
01.
1
<?xml
version=
'1.0'
encoding=
'utf-8'
?>
02.
2
<resources>
03.
3
04.
4
<string
name=
'app_name'
>m05_PrefFragment01</string>
05.
5
<string
name=
'action_settings'
>Settings</string>
06.
6
<string
name=
'hello_world'
>Hello
world!</string>
07.
7
08.
<strong>
8
<string-array
name=
'cities'
>
09.
9
<item>成都</item>
10.
10
<item>重慶</item>
11.
11
<item>黃岡</item>
12.
12
</string-array></strong>
13.
13
14.
14
</resources>
上方代碼中,8至12行:即加粗部分,是我添加的數據源。
運行程序效果如下:
六、監聽事件onPreferenceTreeClick()方法:
1.
public
boolean
onPreferenceTreeClick(PreferenceScreen
preferenceScreen Preference preference)
當任何一個preference控件被點擊,都將觸發該方法。但是可以通過preference.getKey()這個方法找到具體是哪個preference被點擊了,因爲每個preference的key都是唯一的。
【實例】
現將preferences.xml這個設置選項的佈局文件,定義如下:
01.
<?xml
version=
'1.0'
encoding=
'utf-8'
?>
02.
<PreferenceScreen
xmlns:android=
'http://schemas.android.com/apk/res/android'
>
03.
04.
<!--
設置的類別 -->
05.
<PreferenceCategory
06.
android:key=
'mylocation'
07.
android:summary=
'我的位置'
08.
android:title=
'我的位置源'
>
09.
<CheckBoxPreference
10.
android:key=
'wireless_network'
11.
android:summary=
'使用無線網絡查看應用程序(例如Google地圖)中的位置'
12.
android:title=
'使用無線網絡'
/>
13.
<CheckBoxPreference
14.
android:key=
'gps_satellite_setting'
15.
android:summary=
'定位時,精確到街道級別(取消選擇可節約電量)'
16.
android:title=
'啓用GPS衛星設置'
/>
17.
</PreferenceCategory>
18.
19.
<PreferenceCategory
20.
android:key=
'mymessage'
21.
android:summary=
'個人信息設置'
22.
android:title=
'個人信息設置'
>
23.
<CheckBoxPreference
24.
android:key=
'yesno_save_individual_info'
25.
android:title=
'是否保存個人信息'
/>
26.
<EditTextPreference
27.
android:key=
'individual_name'
28.
android:summary=
'請輸入真實姓名'
29.
android:title=
'姓名
'
/>
30.
<ListPreference
31.
android:entries=
'@array/cities'
32.
android:entryValues=
'@array/cities'
33.
android:key=
'mycity'
34.
android:summary=
'所屬城市'
35.
android:title=
'所屬城市'
/>
36.
</PreferenceCategory>
37.
38.
</PreferenceScreen>
運行效果如下:
現在我們需要做的是,選中上方紅框中的CheckBoxPreference,對應下面的EditTextPreference爲編輯狀態;否則,如果CheckBoxPreference沒有被選中,則EditTextPreference爲不可編輯狀態。修改PrefFragment.java的代碼,其完整版代碼如下:
01.
1
package
com.example.m05_preffragment01;
02.
2
03.
3
import
android.os.Bundle;
04.
4
import
android.preference.CheckBoxPreference;
05.
5
import
android.preference.EditTextPreference;
06.
6
import
android.preference.Preference;
07.
7
import
android.preference.PreferenceFragment;
08.
8
import
android.preference.PreferenceScreen;
09.
9
10.
10
public
class
PrefFragment
extends
PreferenceFragment
{
11.
11
12.
12
@Override
13.
13
public
void
onCreate(Bundle
savedInstanceState) {
14.
14
//
TODO Auto-generated method stub
15.
15
super
.onCreate(savedInstanceState);
16.
16
17.
17
//從xml文件加載選項
18.
18
addPreferencesFromResource(R.xml.preferences);
19.
19
}
20.
20
21.
21
@Override
22.
22
public
boolean
onPreferenceTreeClick(PreferenceScreen
preferenceScreen,
23.
23
Preference
preference) {
24.
24
//如果“保存個人信息”這個按鈕被選中,將進行括號裏面的操作
25.
25
if
(
'yesno_save_individual_info'
.equals(preference.getKey()))
{
26.
26
CheckBoxPreference
checkBoxPreference = (CheckBoxPreference)findPreference(
'yesno_save_individual_info'
);
27.
27
EditTextPreference
editTextPreference = (EditTextPreference)findPreference(
'individual_name'
);
28.
28
//讓editTextPreference和checkBoxPreference的狀態保持一致
29.
29
editTextPreference.setEnabled(checkBoxPreference.isChecked());
30.
30
}
31.
31
//
TODO Auto-generated method stub
32.
32
return
super
.onPreferenceTreeClick(preferenceScreen,
preference);
33.
33
}
34.
34
}
代碼解釋:
當任何一個preference控件被點擊,都將觸發onPreferenceTreeClick()方法(22行),但是可以通過preference.getKey()這個方法找到具體是哪個preference被點擊(25行)。
26行、27行:通過public Preference findPreference(CharSequence key)找到對應的preference,然後強轉爲它的子類。
29行:核心代碼,讓editTextPreference和checkBoxPreference的狀態保持一致。
運行效果如下:
這樣,我們的功能就實現了。
文章來源:http://www.cnblogs.com/smyhvae/p/4020469.html