一、前言
任何App都會存在設置界面,如果開發者利用普通控件並綁定監聽事件保存設置,這一過程會非常的枯燥,而且耗時。我們可以看到Android系統的設置界面裡面的選項如此之多,是不是都是這樣開發的呢?其實不然,Android已經給我們提供了專門設計這一功能的技術,叫應用程序首選項,今天我們將學習如何使用他們來開發配置界面以及功能。
二、准備工作
首先需要理解的就是我們設置界面還是需要控件的,但是我們所使用的控件不在是普通的控件,下面我們來簡單的介紹下我們需要知道的控件。
CheckBoxPreference:用來實現勾選的項目,在SharedPreference中保存為bool類型。
EditTextPreference:用來實現字符輸入的項目,在SharedPreference中保存為字符串類型。
ListPreference:用來實現提供一列數據供選擇的項目,在SharedPreference中保存為字符串類型。
PreferenceActivity:首選項活動。
PreferenceCategory:用來實現將首選項進行分類。
PreferenceScreen:用於在另一個新的屏幕上對首選項進行分組。
除了以上的還有其它的這裡就不意義例舉了。
三、正文
1.顯示一個簡單的首選項
首先我們需要打開MainActivity並將繼承的基類改成PreferenceActivity,然後將SetContentView改成AddPreferencesFromResource,具體的代碼如下所示:
1 protected override void OnCreate(Bundle bundle)
2 {
3 base.OnCreate(bundle);
4 AddPreferencesFromResource(Resource.Layout.Main);
5 }
讀者也可以嘗試不修改而直接顯示,當然一定會報錯。
修改好了代碼我們打開Main.axml並將其中的所有xml刪除,改寫成如下所示:
1 <?xml version="1.0" encoding="utf-8"?>
2 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
3 <PreferenceCategory
4 android:title="配置分類1">
5 <CheckBoxPreference
6 android:key="PREF_CHECK_BOX"
7 android:title="Check Box Preference"
8 android:defaultValue="true" />
9 </PreferenceCategory>
10 <PreferenceCategory
11 android:title="配置分類2">
12 <EditTextPreference
13 android:key="PREF_EDIT_BOX"
14 android:title="Edit Text Preference"
15 android:dialogMessage="please input"
16 android:defaultValue="test" />
17 </PreferenceCategory>
18 <PreferenceCategory
19 android:title="配置分類3">
20 <ListPreference
21 android:title="List Preference"
22 android:key="listChoice"
23 android:entries="@array/ListText"
24 android:entryValues="@array/ListValue"
25 android:summary="choice one item" />
26 </PreferenceCategory>
27 <PreferenceCategory
28 android:title="配置分類4">
29 <PreferenceScreen
30 android:title="子配置">
31 <CheckBoxPreference
32 android:key="PREF_CHECK_BOX_1"
33 android:title="Check box"
34 android:defaultValue="true" />
35 </PreferenceScreen>
36 <PreferenceScreen
37 android:title="打開新的意圖">
38 <intent
39 android:action="android.settings.DISPLAY_SETTINGS" />
40 </PreferenceScreen>
41 </PreferenceCategory>
42 </PreferenceScreen>
復制代碼
一部分簡單的,筆者就不多做介紹了。主要是看這段xml代碼:
1 <PreferenceScreen
2 android:title="打開新的意圖">
3 <intent
4 android:action="android.settings.DISPLAY_SETTINGS" />
5 </PreferenceScreen>
其中ListPreference中的entries和entryValue資源如下所示(Strings.xml中):
復制代碼
1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3 <string name="Hello">Hello World, Click Me!</string>
4 <string name="ApplicationName">PreferenceScreen</string>
5 <string-array name="ListText">
6 <item>First</item>
7 <item>Second</item>
8 <item>Third</item>
9 </string-array>
10 <string-array name="ListValue">
11 <item>VFirst</item>
12 <item>VSecond</item>
13 <item>VThird</item>
14 </string-array>
15 </resources>
復制代碼
我們知道了PreferenceScreen會打開一個新的界面去顯示在它內部的首選項,但是內部是一個intent則表示打開指定action的活動,就如同startActivity一樣,這樣的有點就是有助於我們將某些我們需要的設置,但是在系統中已經存在這個設置,我們就可以通過這種方式將其鏈接過去。下面我們運行項目,將可以看到如下的圖像:
相信有些筆者會感覺這有什麼的,顯示的效果跟普通的控件一樣。因為它本身就是利用了普通的控件,當然也不會白利用,因為在內部它已經幫你做好了一大推事情,在這個界面上的每個選項它都已經自動保存進了SharedPreference中,而不需要你去一個一個的綁定事件,然後保存。如果我們需要讀取這些配置只需要通過PreferenceManager的GetDefaultSharedPreferences獲取ISharedPreference類型的對象後通過Get<類型>方法讀取即可,他們的key自然就是控件的android:key屬性的值。這樣我們就節省了不少時間了。
2.監聽首選項更改
雖然我們已經可以讀取配置的值,但是實際的應用中並不是所有的設置都是在下次才啟用。有可能有些設置修改完之後就要修改當前的功能。比如通過設置關閉某個功能,那麼在這個設置選擇下去的同時app也需要立即將對應的功能關閉。這時候我們就要監聽對應的事件,而我們只需要實現ISharedPreferencesOnSharedPreferenceChangeListener接口即可,下面為該接口的代碼:
復制代碼
1 public interface ISharedPreferencesOnSharedPreferenceChangeListener : IJavaObject, IDisposable
2 {
3 void OnSharedPreferenceChanged(ISharedPreferences sharedPreferences, string key);
4 }
復制代碼
其中我們可以看到只要實現一個方法,並且該方法的第二個參數是進行修改的選項的android:key的值,通過key我們就可以在第一個參數中獲取修改後的值,這裡還需要注意的是要根據情況選擇對應類型的Get方法。
筆者為了節省時間,所以我們依然是利用上節的項目,在MainActivity中實現該接口。
代碼如下所示:
復制代碼
1 public void OnSharedPreferenceChanged(ISharedPreferences sharedPreferences, string key)
2 {
3 string value = "";
4 switch (key)
5 {
6 case "PREF_CHECK_BOX":
7 {
8 if (sharedPreferences.GetBoolean(key, false))
9 value = "true";
10 else
11 value = "false";
12 }
13 break;
14 case "PREF_EDIT_BOX":
15 {
16 value = sharedPreferences.GetString(key, "");
17 }
18 break;
19 case "listChoice":
20 {
21 value = sharedPreferences.GetString(key, "");
22 }
23 break;
24 }
25 Toast.MakeText(this, key + "的值改變為" + value, ToastLength.Short).Show();
26 }
復制代碼
筆者僅僅只是根據情況獲取對應的值後通過Toast顯示出來,完成了上面這些還不夠,我們還需要將其進行注冊,所以我們需要利用RegisterOnSharedPreferenceChangeListener和UnregisterOnSharedPreferenceChangeListener方法,下面為具體的代碼:
復制代碼
1 protected override void OnResume()
2 {
3 base.OnResume();
4 PreferenceManager.GetDefaultSharedPreferences(this).RegisterOnSharedPreferenceChangeListener(this);
5 }
6
7 protected override void OnPause()
8 {
9 base.OnPause();
10 PreferenceManager.GetDefaultSharedPreferences(this).UnregisterOnSharedPreferenceChangeListener(this);
11 }
復制代碼
這裡提醒下讀者,筆者在查看《c#開發Android應用實戰》一書中後,采用該書上面的方法,但是監聽事件一直不會被執行,所以參考了Android方面的書籍,而采用了上面的方法。
我們重新運行程序,修改一個項目後將會出現以下的結果:
3.新平台下的應用程序首選項
下面我們將學習Android 3.0後的應用程序首選項如何實現,以開發能夠兼容平板和手機的設置界面。這節筆者建議大家重新創建一個項目,並且Android SDK的版本要在3.0或以上才可以。
首先我們需要設計新的應用程序首選項的xml代碼,筆者的代碼如下所示:
復制代碼
1 <?xml version="1.0" encoding="utf-8"?>
2 <preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
3 <header
4 android:fragment="preferencefragmentstudy.FirstPreferenceFragment"
5 android:title="FirstFragment"
6 android:summary="the first framgnet" />
7 <header
8 android:fragment="preferencefragmentstudy.SecondPreferenceFragment"
9 android:title="SecondFragment"
10 android:summary="the second fragment"></header>
11 </preference-headers>
復制代碼
可以看到這裡的xml標簽在上面是從來沒有使用過的,而每個header都是一個鏈接,會鏈接到由android:fragment指定的碎片,筆者要注意下fragment的路徑是項目名稱的小寫加類名,如果前面是解決方案的大寫會打不開。並且MainActivity還是繼承自PreferenceActivity,只是我們這裡不再重寫OnCreate而是需要重寫OnBuildHeaders方法並調用LoadHeadersFromResource加載上面的xml資源,筆者的代碼如下所示:
復制代碼
1 [Activity(Label = "PreferenceFragmentStudy", MainLauncher = true, Icon = "@drawable/icon")]
2 public class MainActivity : PreferenceActivity
3 {
4 public override void OnBuildHeaders(System.Collections.Generic.IList<PreferenceActivity.Header> target)
5 {
6 LoadHeadersFromResource(Resource.Xml.XMLFile2, target);
7 }
8 }
復制代碼
為了節約時間,另外兩個PreferenceFragment都采用同一個設計,下面為xml的代碼:
復制代碼
1 <?xml version="1.0" encoding="utf-8"?>
2 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
3 <PreferenceCategory
4 android:title="配置分類1">
5 <CheckBoxPreference
6 android:key="PREF_CHECK_BOX"
7 android:title="Check Box Preference"
8 android:defaultValue="true" />
9 </PreferenceCategory>
10 </PreferenceScreen>
復制代碼
這裡我們可以看到熟悉的標簽了,下面我們開始設計PreferenceFragment,他們的代碼分別如下所示:
復制代碼
1 public class FirstPreferenceFragment : PreferenceFragment
2 {
3 public override void OnCreate(Bundle bundle)
4 {
5 base.OnCreate(bundle);
6 AddPreferencesFromResource(Resource.Xml.XMLFile1);
7 }
8 }
復制代碼
復制代碼
[Activity(Label = "SecondPreferenceFragment")]
public class SecondPreferenceFragment : PreferenceFragment
{
public override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
AddPreferencesFromResource(Resource.Xml.XMLFile1);
}
}
復制代碼