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

Android 首选项框架及PreferenceScreen,PreferenceActivity,PreferenceFragment的用法与分析

2016-01-05 15:18 726 查看

前言

《Android 4 高级编程(第3版)》第7章第5节讲到了首选项框架和PreferenceActivity概述等内容,因为第一次见到PreferenceScreen,还没用过,所以心情难免有点小激动。那google官方为什么要出这么个东东,它又有什么好处呢?让我们带着这些个问题,一起去进行探索吧!

提纲

这篇文章我们会从以下几个知识点进行学习:

PreferenceScreen

Preference

PreferenceActivity

PreferenceFragment

正文

Preference

它相当于一个View,在xml中由它的子类节点来展示相应的控件

CheckBoxPreference:类似CheckBox,

ListPreference:这个类是继承自DialogPreference,当点击它时,它会弹出Dialog来展示数据,比如:城市选择

SwitchPreference:是一个内含有2种状态的ToggleButton的控件

EditTextPreference:继承自DialogPreference,里面持有EditText输入框,与ListPreference一样,以对话框呈现。

PreferenceScreen

官方源码给出的注释的意思大概如下:

这是一个代表包装一系列Preference视图树的一个根节点。在xml中PreferenceScreen可以出现在2个地方:根节点Preference视图树中间

A),当做为根节点时,PreferenceScreen不会显示,即只在当前一屏;

B),当在视图层级中间时,代表是一个新的屏幕,当点击它时,会另开一屏

下面是一个简单的xml布局文件,包含了PreferenceScreen,Preference

注:Preference的xml文件放在res/xml文件夹下,没有xml文件夹时,自己创建

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<Preference
android:key="title"
android:layout="@layout/item_titlebar" />

<PreferenceCategory
android:title="性别"
>
<CheckBoxPreference
android:key="preference_sex_man"
android:title="男"/>
<CheckBoxPreference
android:key="preference_sex_woman"
android:title="女"/>
<SwitchPreference
android:key="switch"
android:title="wifi"
/>
<PreferenceScreen
android:key="wifisetting"
android:title="WifiSetting">
<SwitchPreference
android:key="sencond_preferencScreen"
android:title="SencondPreference"/>
<!-- <!–也可以直接用intent跳转到指定Activity–>
<intent
android:action="android.intent.action.VIEW"
android:data="http://www.baidu.com">
</intent>-->
</PreferenceScreen>
</PreferenceCategory>

<PreferenceCategory
android:title="城市选择">

<ListPreference
android:key="city_choose"
android:title="城市选择"
android:summary="点击进行城市选择"
android:entries="@array/cities_name"
android:entryValues="@array/cities_name"></ListPreference>
</PreferenceCategory>

<PreferenceCategory
android:title="昵称">
<EditTextPreference
android:key="nickName_edit"
android:title="修改昵称"
android:summary="点击进行昵称修改"
android:dialogTitle="修改昵称"
android:dialogMessage="确认修改?"></EditTextPreference>
</PreferenceCategory>

</PreferenceScreen>


这个布局文件对应的UI如下:



3.PreferenceActivity与PreferenceFragment

在Android1.0的时候,官方就有了PreferenceActivity,这个类继承自ListActivity,是一个抽象类,其持有PreferenceManager对象的引用。在Android3.0时,由于Fragment的出现,官方同步支持了PreferenceFragment,同时,PreferenceActivity中的一些API也被相应标记为过时,官方给出的解释是:因为PreferenceActivity这个类仅仅只被允许展示一个单独的偏好设置,而这些现在都能在PreferenceFragment中找到了,其实从中可以看出google官方的思想是用碎片化来达到解藕

eg:

新建一个Activity,继承自PreferenceActivity,

/**
* Created by sunny on 2016/1/5.
* 首选项设置,
*/
public class TestPrefeerenceActivity extends PreferenceActivity implements Preference.OnPreferenceChangeListener
, SharedPreferences.OnSharedPreferenceChangeListener {

public static final String TAG = TestPrefeerenceActivity.class.getSimpleName();

private SharedPreferences mSharePreference;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//注意:这里不再用setContentView,改用addPreferencesFromResource(),
//setContentView(R.layout.activity_test_preference);
addPreferencesFromResource(R.xml.test_preference);

mSharePreference = PreferenceManager.getDefaultSharedPreferences(this);
//由PreferenceManager获取SharedPreferences对象的引用
initView();
bindView();
}

@Override
protected void onResume() {
super.onResume();
freshUI();
mSharePreference.registerOnSharedPreferenceChangeListener(this);
}

private void freshUI() {
mListPreference.setTitle(mSharePreference.getString("city_choose","null"));
mEditPreference.setTitle(mSharePreference.getString("nickName_edit","null"));
}


下面是获取Preference控件实例的方法,与findViewById()相似:

private void initView() {
mTitleBar = findPreference("title");
//这里的title是一个key,也即SharePreference中用来存储数据的key.
mListPreference = (ListPreference) findPreference("city_choose");
mCBPreferenceMan = (CheckBoxPreference) findPreference("preference_sex_man");
mCBPreferenceWoman = (CheckBoxPreference) findPreference("preference_sex_woman");
mEditPreference = (EditTextPreference) findPreference("nickName_edit");

}


最后实现onPreferenceChange监听

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference instanceof EditTextPreference) {
mEditPreference.setTitle(newValue.toString());
mEditPreference.setText(newValue.toString());
mEditPreference.setDefaultValue(newValue);
} else if (preference instanceof ListPreference) {

mListPreference.setValue(newValue.toString());
mListPreference.setTitle(newValue.toString());
} else if (preference instanceof CheckBoxPreference) {
changeCBState(preference);
}
return false;
}

private void changeCBState(Preference preference) {
if (preference == mCBPreferenceMan) {
checkCheckBoxPreference(preference, mCBPreferenceWoman);
} else {
checkCheckBoxPreference(preference, mCBPreferenceMan);
}
}


实例

demo:github地址SunnyDemoProject/sunnydemo2

总结

现在由于APP的高度定制化,除了系统的设置界面,第三方的应用几乎都没有用到PreferenceActivity或PreferenceFragment,

不过从中可以学到google的一种封装思想,界面与Preference分离,

然后通过PreferenceManager来连接界面与Preference,实现SharePreference对数据进行存储与读取,做到解藕。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: