您的位置:首页 > 移动开发 > Android开发

android中使用Preference API实现设置界面

2016-01-02 16:03 856 查看

Android使用Preference API快速实现设置界面

在移动应用中,几乎每个应用都有一个叫做“设置”的地方,那里包含了用户对应用的一些设置。几乎每个应用的设置都是差不多的,无外乎外观的一些差别,可是,如果认为就是几个TextView或者EditText控件的简单拼凑,那就太小看系统的设计者了,在Android中,我们使用Preference这一类和相关的API实现

我们并不会在布局文件中写具体的view,而是在res目录下新建一个xml文件夹,新建一般名为preferences(可随意指定)的xml文件,设置是在文件中使用Preference类的子类构建而成。就像这样:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:key="catogory"
android:title="种类">
<CheckBoxPreference
android:defaultValue="true"
android:key="wifi"
android:summary="在wifi的环境才让下载工作继续"
android:title="只在wifi环境可下载" />
<EditTextPreference
android:hint="请输入姓名"
android:key="name"
android:title="姓名:">
</EditTextPreference>
</PreferenceCategory>
</PreferenceScreen>


PreferenceSreen,PreferenceCatogory等均是Prefence的扩展类。各有个的效果,如图
如ListPreference之类的必须放在PreferenceCategory中,PreferenceCategory必须放在PreferenceScreen中
![上述代码的实际效果](https://img-blog.csdn.net/20151229233935985)


你添加的每一个Preference,都有一个相对应的键值对,每次出现更改时,系统自动会将修改的值保存在应用默认的SharePreference文件中,你可以读取该文件中相应的值,做出你想做的修改。是不是相比于自己去写控件,这种直接操作xml文件的方式更加强大和方便呢。

如何实现上述效果呢,分三种情况,

采用继承PreferenceActivity显示设置界面

继承PreferenceFragment的Fragment(片段)来显示设置界面,托管该Fragment的activity继承一般的activity即可。

以上两种的结合

第三种是最终建议使用的方式,因为第三种使用了一种方法同时适配了手机和平板两种设置。想要了解第三种,不急,一定要了解前两种方式

第一种,继承PreferenceActivity

这是传统Activity的扩展,该类根据Preference对象的层级结构显示设置列表,当用户更改时,PreferenceActivity会自动保留每个用户的修改

public class SettingsActivity extends PreferenceActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);//在oncreate中加入这一行代码
}
}


第二种,继承PrefrenceFragment

public static class SettingsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
...
}
//注意 ,PrefrenceFragment没有自己的Context对象,需要的话,应从其所依附的activity中获取,在onActivityCreate()中或之后的回调中获取


public class SettingsActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
}


通过以上两种方法建立Xml设置首选项后,在应用首次进入时,可能需要里面的值,在用户没有来得及设置之前,一些重要的功能可能需要用到里面的值,所以,有必要为每个设置默认值,通过

android:defalutValue=""//boolean,string等类型的值
//Preference API 所支持的数据类型有:boolean,float,int,long,string


第三种,使用标头

xml文件的根节点元素为preference-headers,元素内的单个header元素指定,例如:

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<header
android:fragment="com.ex
c874
ample.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>


显示标头:

public class SettingsActivity extends PreferenceActivity {
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preference_headers, target);
}
}


下面是一个Android 3.0以上的xml标头文件

<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<header
android:fragment="com.example.prefs.SettingsFragmentOne"
android:title="@string/prefs_category_one"
android:summary="@string/prefs_summ_category_one" />
<header
android:fragment="com.example.prefs.SettingsFragmentTwo"
android:title="@string/prefs_category_two"
android:summary="@string/prefs_summ_category_two" />
</preference-headers>


Activity中:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {//保证在3.0以上才调用,因为标头是在3.0以后引入的
addPreferencesFromResource(R.xml.preference_headers_legacy);
}
}

//3.0后才会调用
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preference_headers, target);
}


读取首选项

默认情况下,应用首选项默认都保存到一个可通过调用静态方法:PrefrenceManager.getDefaultSharePreference()从应用的任何位置访问的文件中。这将返回SharePreference对象。这其中包括与Preference想关联的Preference对象的所有键值对

SharedPrefences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, "");


侦听首选项变更

不多少,直接上代码:

public class SettingsActivity extends PreferenceActivity
implements OnSharedPreferenceChangeListener {
public static final String KEY_PREF_SYNC_CONN = "pref_syncConnectionType";
...

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if (key.equals(KEY_PREF_SYNC_CONN)) {
Preference connectionPref = findPreference(key);
// Set summary to be the user-description for the selected value
connectionPref.setSummary(sharedPreferences.getString(key, ""));
}
}
}
//在此示例中,该方法检查更改的设置是否是针对已知的首选项键。它调用 findPreference() 来获取已更改的 Preference 对象,以便能够将项目摘要修改为对用户选择的说明。即,如果设置为 ListPreference 或其他多选设置时,则当设置更改为显示当前状态(例如,图 5 所示的“Sleep”设置)时,您应调用 setSummary()。


建议在Activity中的onResume()和onPause()中注册和解注册SharedPreferences.OnSharedPreferenceChangeListener

@Override
protected void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}

@Override
protected void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}


储存对侦听器的强引用

注意:目前,首选项管理器不会在您调用 registerOnSharedPreferenceChangeListener() 时存储对侦听器的强引用。但是,您必须存储对侦听器的强引用,否则它将很容易被当作垃圾回收。 我们建议您将对侦听器的引用保存在只要您需要侦听器就会存在的对象的实例数据中。

例如,在以下代码中,调用方未保留对侦听器的引用。 因此,侦听器将容易被当作垃圾回收,并在将来某个不确定的时间失败:

prefs.registerOnSharedPreferenceChangeListener(
// 不好,会被垃圾收集器当作垃圾对象并回收
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// 侦听器的实现
}
});


有鉴于此,请将对侦听器的引用存储在只要需要侦听器就会存在的对象的实例数据字段中:

SharedPreferences.OnSharedPreferenceChangeListener listener =
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// 侦听器的实现
}
};
prefs.registerOnSharedPreferenceChangeListener(listener);


基本的介绍就在这里,如果要了解更全面的知识,请到谷歌官方文档查看有Preference API的相关选项,本文的例子程序也多数来自那里
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Preference 设置