在Ap中有时须要设置一些配置参数,这些参数经过配置文件保存。
为了设置这些参数,须要提供一个UI,针对这种需求,Android提供了preferenceActivity。
PreferenceActivity经过读取预先定义的xml文件来生成界面,并可以自动的根据用户的操做来修改参数,并保存到配置文件中供读取。
1.MainActivity:
按下Menu按键弹出菜单,点击菜单启动SettingActivity。
2.SettingActivity继承自PreferenceActivity:
android
@Override 函数
protected void onCreate(Bundle savedInstanceState) { 布局
super.onCreate(savedInstanceState); this
addPreferencesFromResource(R.xml.settings); spa
} rest
在onCreate函数中加载参数定义文件。
xml
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key); blog
当参数值被改变时会调用此Listener,能够在此Listener中做一些界面刷新工做,好比当前参数值改变为新的值。
Preference android.preference.PreferenceActivity.findPreference(CharSequence key);
获取指定key所对应的preference对象,即便此key在配置文件中还没有保存,也可以获得preference对象,而不会是null。
3.settings.xml:保存在xml目中的参数定义文件,在建立Android XML文件时选择Preference便可建立一个空的参数定义文件。
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
</PreferenceScreen>
添加一个CheckBoxPreference子项,并设置属性:
Key:checkbox_key
Title:CheckBox Item
Summary:test check box item
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference android:key="checkbox_key"
android:title="CheckBox Item" android:summary="test check box item"></CheckBoxPreference>
</PreferenceScreen>
key是用来访问此参数的值的关键字,保存后的配置文件相似以下内容:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<boolean name="checkbox_key" value="true" />
</map>
启动Ap,点击菜单,便可看到参数设置界面,而且当用户点击操做改变了参数值后,也会被自动保存。
4.使用参数值:
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
boolean check_test = sp.getBoolean("checkbox_key", false);
进阶:
1.保存参数文件的路径:
/data/data/包名/shared_prefs/包名_preferences.xml
若是想指定保存文件名,可以使用:
getPreferenceManager().setSharedPreferencesName("配置文件名");
2.其余的参数配置项:
2.1 EditTextPreference:
<EditTextPreference android:dialogTitle="Edit Text Dialog"
android:key="edittext_key" android:dialogMessage="Please Input text"
android:title="EditText Item" android:summary="test edittext item"></EditTextPreference>
此参数设置项会弹出一个文本输入对话框,并在配置文件中生成相似如下内容:
<string name="edittext_key">this is a good text</string>
弹出对话框的图标、标题、提示信息、Icon、以及两个按钮的文本均可以设定。
至于自定义对话框的布局,虽然有这个属性,可是自定义布局后就不能自动保存值了,
原本觉得只要放一个ID和原来同样的EditText就能,可是查看源代码,发现其EditText是new出来的,无法替代。
2.2 PreferenceCategory:一个分类分隔条。只有title属性有效。
2.3 PreferenceScreen:此项包含的全部子项在新屏幕上显示,就好像进入二级菜单。
2.4 ListPreference:会弹出一个列表对话框供选择。
2.5 RingtonePreference:会弹出系统铃声列表供选择。
2.6 Preference:通用参数项。点击后须要程序本身响应事件。
3.自定义选项:
系统的提供的界面有时不能知足须要,这时就须要自定义选项了。
有两种方法能够实现自定义选项,一是用Preference做为选项,并从新实现onPreferenceTreeClick函数。
一是自定义一个类,相似于EditTextPreference这种系统内置的类,而后引用。
3.1使用一个Preference占位,而后从新实现onPreferenceTreeClick()函数:
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
String key = preference.getKey();
if( key != null ){
if(key.equals("some_key")) {
showDialog(DIALOG_SOME_KEY);
}
}
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
当点击指定key的Preference时,就会弹出对话框,而后在合适的时机使用以下代码保存参数便可。
SharedPreferences.Editor editor = preference.getEditor();
editor.putLong("ttt", 123);
editor.commit();
此种方法若是要触发onSharedPreferenceChanged(),能够经过preference.getOnPreferenceChangeListener()获取listener而后来呼叫。
3.2自定义选项类:
此处以一个选择时间的对话框选项为例。
3.2.1 从DialogPreference继承一个类:
public class TimePreference extends DialogPreference
3.2.2 构造函数:
public TimePreference(Context context, AttributeSet attrs) {
super(context, attrs);
setDialogLayoutResource(R.layout.time_preference); //加载布局文件
}
3.3.3 布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TimePicker android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/timePicker_preference" android:layout_centerHorizontal="true"></TimePicker>
</RelativeLayout>
定义了一个id为timePicker_preference的TimePicker。
3.3.4 界面初始化:在dialog的函数中经过id找到TimePicker,而后使用已经存储的值或者默认值,再设置到TimerPicker中。
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
mPicker = (TimePicker)view.findViewById(R.id.timePicker_preference);
if(mPicker != null) {
mPicker.setIs24HourView(true);
long value = mValue;
Date d = new Date(value);
mPicker.setCurrentHour(d.getHours());
mPicker.setCurrentMinute(d.getMinutes());
}
}
3.3.5 保存值:在对话框关闭时保存值。
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if(positiveResult) {
Date d = new Date(0, 0, 0, mPicker.getCurrentHour(), mPicker.getCurrentMinute(), 0);
long value = d.getTime();
if(callChangeListener(value)) {
setValue(value);
}
}
}
3.3.6 使用此preference:
在参数定义文件中增长:
<cn.demo.pa.TimePreference android:key="time_test" android:title="Test time preference"/>
相似于使用自定义控件。
运行便可看到效果:
3.3.7 使用默认值:
在参数定义文件中增长一个定义:
<cn.demo.pa.TimePreference android:key="time_test" android:title="Test time preference" android:defaultValue="1000000"/>
而且自定的preference类中要实现两个函数:
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getString(index);
}
以及
@Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
long value;
if(restorePersistedValue) value = getPersistedLong(0);
else {
value = Long.parseLong(defaultValue.toString());
}
setValue(value);
}
当PreferenceActivity启动时会构造TimePreference,此时会调用onGetDefaultValue,而后调用onSetInitialValue,在onSetInitialValue保存初始值,并在onBindDialogView中使用保存的值从而可使用默认值。
原文路径:http://mypyg.iteye.com/blog/839501