app都有设置界面,一般都是我们自定义的,其实Android已经为我们提供了类PreferenceActivity、PreferenceFragment来实现设置界面。 使用 PreferenceActivity继承ListActivity,所以多个Preference可以像ListView那样滑动。 值是存放在SharedPreferences而不是Preference
PreferenceScreen是根布局,可以嵌套其它xxPreference,也可以签到自己。
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:key="root" android:summary="summary" android:title="root"> <PreferenceScreen android:summary="EditText" android:title="第一组"> <EditTextPreference android:defaultValue="@string/defaultValue" android:summary="summary" android:title="EditText"/> </PreferenceScreen> <PreferenceScreen android:summary="CheckBox" android:title="第二组"> <CheckBoxPreference android:defaultValue="true" android:summary="summary" android:title="EditText"/> </PreferenceScreen> </PreferenceScreen>entries是ListPreference显示的内容,entryValues是获取的值,显示等到内容和值是不一样的。
<string-array name="provinces1"> <item>shandong</item> <item>jiangsu</item> <item>zhejiang</item> <item>fujian</item> </string-array> <string-array name="provinces2"> <item>山东</item> <item>江苏</item> <item>浙江</item> <item>福建</item> </string-array> <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <ListPreference android:key="listPre" android:title="ListPre" android:summary="list_pre" android:entries="@array/provinces1" android:entryValues="@array/provinces2" android:dialogTitle="dialogTitle" android:defaultValue="@string/app_name"/> </PreferenceScreen>通过key获取对象:
ListPreference listPre = (ListPreference) findPreference("listPre");获取key:
Preference pref; pref.getKey()获取ListPreference选中的值:
listPre.getValue()在监听中也可以获取,object就是value
listPre.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference pref, Object object) { LogUtil.d("key=" + pref.getKey()+",value="+(String)object); return false; } });返回true和false的区别:
false:不会保存change结果 true:保存change结果
获取SharedPreferences
Preference pref; pref.getSharedPreferences()decimal:浮点数,signed:带符号整数,integer:整数
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <EditTextPreference android:defaultValue="@string/defaultValue" android:dialogTitle="DialogTitle" android:key="et1" android:numeric="integer" android:summary="简要说明" android:title="title"/> </PreferenceScreen>checked textOn switchTextOn 是无效(4.x系统上有效)的,android:checked="true"是有效的。
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <SwitchPreference android:key="switch1" android:switchTextOn="一打开" android:checked="true" android:title="通知"/> <SwitchPreference android:key="switch2" android:textOn="djla" android:checked="false" android:title="通知2"/> <SwitchPreference android:key="switch3" android:title="通知3"/> </PreferenceScreen><?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <RingtonePreference android:key="ringtone1" android:title="Ringtone"/> </PreferenceScreen>
defaultValue无效
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <MultiSelectListPreference android:defaultValue="@array/provinces2" android:entries="@array/provinces2" android:entryValues="@array/provinces2" android:key="multi_select_list_preference_1" android:title="Multi select list preference"/> </PreferenceScreen>分组
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="Category"> <CheckBoxPreference android:title="范冰冰"/> <Preference android:summary="summary范冰冰" android:title="选择范冰冰"> </Preference> <Preference android:title="选择范冰冰2"/> </PreferenceCategory> <PreferenceCategory android:title="Category"> <CheckBoxPreference android:title="李冰冰" /> <Preference android:title="选择李冰冰"/> <Preference android:title="选择李冰冰2"/> </PreferenceCategory> </PreferenceScreen>使用方式有2种:
Activity继承PreferenceActivity,调用方法addPreferencesFromResource(R.xml.pre_list);该方法过时了,官方不在推荐Fragment继承PreferenceFragment,在onCreate()中调用方法addPreferencesFromResource(R.xml.pre_list);,这是官方推荐的,官方推荐用fragment如果加入Header,必须重写方法onBuildHeaders(...)和isValidFragment(...) isValidFragment():使用使用Fragment onBuildHeaders(...):填充header
@Override protected boolean isValidFragment(String fragmentName) { return true; } @Override public void onBuildHeaders(List<Header> target) { loadHeadersFromResource(R.xml.pre_header, target); }如果header中加入其它view
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (hasHeaders()) { Button button = new Button(this); button.setText("Some action"); setListFooter(button); } }Activity继承的是Activity,而不是PreferenceActivity
public class Main2Activity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); PreFragment frag = new PreFragment(); getFragmentManager().beginTransaction().replace(R.id.frameLayout,frag,"PreFragment").commit(); } } public class PreFragment extends PreferenceFragment { @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.pre_fragment); } }填充布局(类似于setContentView(R.layout.activity_main);),可以调用多次
addPreferencesFromResource(R.xml.pre_check_box)找到控件(类似findViewById(resId)):
ListPreference listPre = (ListPreference) findPreference("listPre"); CheckBoxPreference cbPre = (CheckBoxPreference) findPreference("cb1");获取SharedPreferences的值:
SharedPreferences prefs prefs.getString(key, ""); prefs.getBoolean(key, false)获取key:
Preference pref; pref.getKey()获取SharedPreferences
Preference pref; pref.getSharedPreferences()给xxPreference设置点击事件setOnPreferenceClickListener
listPre.setOnPreferenceClickListener(this); @Override public boolean onPreferenceClick(Preference pref) { String key = pref.getKey(); String value = pref.getSharedPreferences().getString(key,""); LogUtil.d("list_pre key=" +key +",value="+value); switch (pref.getKey()) { case "listPre": break; } return false; }setOnPreferenceChangeListener(...)只是给单个preference设置的,一个设置界面有很多preference,如果每个都这么写,那么跟onClickListener(...)就没什么区别了,也不方便,官方也就不用提供了preference,那么有没有一个方法,只设置一次,就相当于给所有的preference设置监听呢?很明显是有的。
这样就相当于给所有的preference设置了监听:
@Override protected void onResume() { super.onResume(); getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); } @Override protected void onPause() { super.onPause(); getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); }当前类实现OnSharedPreferenceChangeListener
public class MainActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener重写方法:
@Override public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {//sharedPreferences switch (key) { case "listPre": LogUtil.d("key=" + key + ",value=" + prefs.getString(key, "")); listPre.setSummary(prefs.getString(key, "")); break; case "cb1": LogUtil.d("key=" + key + ",value=" + prefs.getBoolean(key, false)); break; case "cb2": LogUtil.d("key=" + key + ",value=" + prefs.getBoolean(key, false)); break; } }Demo:http://git.oschina.net/AndroidUI/prerefenceactivitypreferencefragment 官方文档: https://developer.android.google.cn/guide/topics/ui/settings.html#Fragment