大多數時候我們都是這樣去使用SharedPreferences
SharedPreferences sharedPreferences = getSharedPreferences("eric", Context.MODE_PRIVATE); //私有數據
Editor editor = sharedPreferences.edit();//獲取編輯器
editor.putString("name", "eric");
editor.putInt("age", 4);
editor.commit();//提交修改
在app設置頁面的開發中也會用到對設置項的保存,我們也會用到SharedPreferences去保存這些設置項,Android官方提供了更為簡單針對設置頁面使用SharedPreferences方法,那就是PreferenceActivity和PreferenceFragment. 下面來說下如何使用.
PreferenceActivity主要針對3.0以前的版本,PreferenceFragment則更為靈活,其實使用方法上面兩者大致一樣,所以PreferenceActivity就不展開講解,直接來看PreferenceFragment的使用
一般來說Fragment會要求去關聯一個布局的layout, 但是在PreferenceFragment則不需要這樣做,我們需要去自定義一個xml加入首選項(首選項就是配置項,官方稱為首選項). xml根節點必須是一個PreferenceScreen元素. PreferenceScreen里面的子項都作為一個獨立的控件顯示在界面里,同時還具備保存屬性.
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="checkbox_preference"
android:title="@string/title_checkbox_preference"
android:summary="@string/summary_checkbox_preference" />
<ListPreference
android:key="list_preference"
android:title="@string/title_list_preference"
android:summary="@string/summary_list_preference"
android:entries="@array/entries_list_preference"
android:entryValues="@array/entryvalues_list_preference"
android:dialogTitle="@string/dialog_title_list_preference" />
</PreferenceScreen>
顯示效果如下
以上只展示了CheckBoxPreference和ListPreference,還有其它很多Preference控件,具體可以查閱官方文檔有關Preference的字類.
如果設置項目過多,我們可以進行分類展示,有如下兩種方式可以來實現.
使用標題
加入PreferenceCategory的屬性可以進行標題的劃分.
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/inline_preferences">
<CheckBoxPreference
android:key="checkbox_preference"
android:summary="@string/summary_checkbox_preference"
android:title="@string/title_checkbox_preference"/>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/inline_preferences">
<CheckBoxPreference
android:key="checkbox_preference"
android:summary="@string/summary_checkbox_preference"
android:title="@string/title_checkbox_preference"/>
<ListPreference
android:dialogTitle="@string/dialog_title_list_preference"
android:entries="@array/entries_list_preference"
android:entryValues="@array/entryvalues_list_preference"
android:key="list_preference"
android:summary="@string/summary_list_preference"
android:title="@string/title_list_preference"/>
</PreferenceCategory>
</PreferenceScreen>
使用子屏幕
使用PreferenceCategory屬性可以劃分子屏幕
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/inline_preferences">
<CheckBoxPreference
android:key="checkbox_preference"
android:summary="@string/summary_checkbox_preference"
android:title="@string/title_checkbox_preference"/>
</PreferenceCategory>
<PreferenceScreen
android:key="button_voicemail_category_key"
android:title="Voice mail"
android:persistent="false">
<CheckBoxPreference
android:key="checkbox_preference"
android:summary="@string/summary_checkbox_preference"
android:title="@string/title_checkbox_preference"/>
<ListPreference
android:dialogTitle="@string/dialog_title_list_preference"
android:entries="@array/entries_list_preference"
android:entryValues="@array/entryvalues_list_preference"
android:key="list_preference"
android:summary="@string/summary_list_preference"
android:title="@string/title_list_preference"/>
</PreferenceScreen>
</PreferenceScreen>
配置intent跳轉相應的activity
有時候我們的設置項目并不是保存一個配置項,而是去跳轉到一個新的畫面. 我們可以使用如下配置來使得首選項跳轉一個網頁
<Preference android:title="@string/prefs_web_page" >
<intent android:action="android.intent.action.VIEW"
android:data="http://www.example.com" />
</Preference>
當然你也可以配置顯式的intent進行跳轉,具體可以參見官方文檔.
可以設置默認值給Preference控件
<!-- default value is a boolean -->
<CheckBoxPreference
android:defaultValue="true"
... />
<!-- default value is a string -->
<ListPreference
android:defaultValue="@string/pref_syncConnectionTypes_default"
... />
在進入設置頁面可以調用
PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
對默認值進行初始化應用, 這個接口最常用的地方就是去恢復設置.
使用首選項標頭
通常還有種需求是點擊一個首選項跳轉到另外一個屏幕,當然這個功能也可以通過PreferenceScreen來完成,但是使用PreferenceScreen不能兼容平板的情況就像下面這樣
如果要實現這種效果就要使用到hearders
<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<header
android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentOne"
android:title="@string/prefs_category_one"
android:summary="@string/prefs_summ_category_one" />
<header
android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentTwo"
android:title="@string/prefs_category_two"
android:summary="@string/prefs_summ_category_two" >
<!-- key/value pairs can be included as arguments for the fragment. -->
<extra android:name="someKey" android:value="someHeaderValue" />
</header>
</preference-headers>
android:fragment用來標記點擊后跳轉的Fragment,extra用來傳遞參數,可以在Fragment中通過getArguments()來獲取傳遞過來的bundle數據, 這個數據最大的作用就是用來在同一個preference fragment中加載不同的preference xml.
public static class SettingsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String settings = getArguments().getString("settings");
if ("notifications".equals(settings)) {
addPreferencesFromResource(R.xml.settings_wifi);
} else if ("sync".equals(settings)) {
addPreferencesFromResource(R.xml.settings_sync);
}
}
}
如果要顯示這個標頭文件的內容需要去重寫onBuildHeaders方法.
public class SettingsActivity extends PreferenceActivity {
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preference_headers, target);
}
}
preference-headers這個標簽只能支持3.0以后的版本,如果要兼容3.0以前的版本需要另外在寫個xml作為兼容
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<Preference
android:title="@string/prefs_category_one"
android:summary="@string/prefs_summ_category_one" >
<intent
android:targetPackage="com.example.prefs"
android:targetClass="com.example.prefs.SettingsActivity"
android:action="com.example.prefs.PREFS_ONE" />
</Preference>
<Preference
android:title="@string/prefs_category_two"
android:summary="@string/prefs_summ_category_two" >
<intent
android:targetPackage="com.example.prefs"
android:targetClass="com.example.prefs.SettingsActivity"
android:action="com.example.prefs.PREFS_TWO" />
</Preference>
</PreferenceScreen>
再以如下方式加載
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
// Load the legacy preferences headers
addPreferencesFromResource(R.xml.preference_headers_legacy);
}
}
// Called only on Honeycomb and later
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preference_headers, target);
}
onBuildHeaders這個回調只會在Build.VERSION_CODES.HONEYCOMB(3.0系統)以上的版本調用。
另外我們必須要注意的一點,目前首選項不會再您調用registerOnSharedPreferenceChangeListener()時存儲對監聽器的強引用。但是,您必須存儲對監聽器的強引用,否則它將很容易被當作垃圾回收。
上面就是關于如何使用系統提供具有Preference功能的UI控件來打造一個設置界面. 更多詳細關于自定義Preference等可以參考官方文檔 https://developer.android.com/guide/topics/ui/settings