原文:Xamarin.Android開發實踐(十五)html
任何App都會存在設置界面,若是開發者利用普通控件並綁定監聽事件保存設置,這 一過程會很是的枯燥,並且耗時。咱們能夠看到Android系統的設置界面裏面的選項如此之多,是否是都是這樣開發的呢?其實否則,Android已經給 咱們提供了專門設計這一功能的技術,叫應用程序首選項,今天咱們將學習如何使用他們來開發配置界面以及功能。android
首先須要理解的就是咱們設置界面仍是須要控件的,可是咱們所使用的控件不在是普通的控件,下面咱們來簡單的介紹下咱們須要知道的控件。c#
CheckBoxPreference:用來實現勾選的項目,在SharedPreference中保存爲bool類型。app
EditTextPreference:用來實現字符輸入的項目,在SharedPreference中保存爲字符串類型。ide
ListPreference:用來實現提供一列數據供選擇的項目,在SharedPreference中保存爲字符串類型。post
PreferenceActivity:首選項活動。學習
PreferenceCategory:用來實現將首選項進行分類。ui
PreferenceScreen:用於在另外一個新的屏幕上對首選項進行分組。this
除了以上的還有其它的這裏就不意義例舉了。url
首先咱們須要打開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屬性的值。這樣咱們就節省了很多時間了。
雖然咱們已經能夠讀取配置的值,可是實際的應用中並非全部的設置都是在下次才啓 用。有可能有些設置修改完以後就要修改當前的功能。好比經過設置關閉某個功能,那麼在這個設置選擇下去的同時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方面的書籍,而採用了上面的方法。
咱們從新運行程序,修改一個項目後將會出現如下的結果:
下面咱們將學習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); } }
每一個PreferenceFragment均可以單獨使用第二節的技術,下面咱們查看最後運行的結果:
點中第一以後:
利用該技術能夠在須要大量配置選項的時候可以有條不紊的設計並歸類。