说明
app都有设置界面,一般都是我们自定义的,其实Android已经为我们提供了类PreferenceActivity
、PreferenceFragment
来实现设置界面。
使用
PreferenceActivity
继承ListActivity
,所以多个Preference
可以像ListView
那样滑动。
值是存放在SharedPreferences
而不是Preference
分类
PreferenceScreen
ListPreference
CheckBoxPreference
EditTextPreference
MultiSelectListPreference
RingtonePreference
SwitchPreference
PreferenceCategory
PreferenceScreen
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>
ListPreference
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()
EditTextPreference
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>
SwitchPreference
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>
RingtonePreference
<?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>
MultiSelectListPreference
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>
PreferenceCategory
分组
<?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
PreferenceActivity
public class MainActivity extends PreferenceActivity
如果加入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);
}
}
PreferenceFragment
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);
}
}
方法说明
addPreferencesFromResource(CharSequence)
填充布局(类似于setContentView(R.layout.activity_main);
),可以调用多次
addPreferencesFromResource(R.xml.pre_check_box)
findPreference(CharSequence)
找到控件(类似findViewById(resId)
):
ListPreference listPre = (ListPreference) findPreference("listPre");
CheckBoxPreference cbPre = (CheckBoxPreference) findPreference("cb1");
getXX(key,defaultValue)
获取SharedPreferences
的值:
SharedPreferences prefs
prefs.getString(key, "");
prefs.getBoolean(key, false)
获取key:
Preference pref;
pref.getKey()
获取SharedPreferences
Preference pref;
pref.getSharedPreferences()
setOnPreferenceClickListener(…)
给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(…)
listPre.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference pref, Object o) {
LogUtil.d("list_pre onPreferenceChange key=" + pref.getKey()+",O="+(String)o);
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