PreferenceFragmen基本使用

一、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, EditTextPreferenceListPreference, 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:entriesandroid: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

發佈了20 篇原創文章 · 獲贊 23 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章