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

前言

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

提纲

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

  1. PreferenceScreen
  2. Preference
  3. PreferenceActivity
  4. PreferenceFragment

正文

  1. Preference

    它相当于一个View,在xml中由它的子类节点来展示相应的控件
    CheckBoxPreference:类似CheckBox,
    ListPreference:这个类是继承自DialogPreference,当点击它时,它会弹出Dialog来展示数据,比如:城市选择
    SwitchPreference:是一个内含有2种状态的ToggleButton的控件
    EditTextPreference:继承自DialogPreference,里面持有EditText输入框,与ListPreference一样,以对话框呈现。

  2. 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"/>
                 <!-- &lt;!&ndash;也可以直接用intent跳转到指定Activity&ndash;&gt;
            <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对数据进行存储与读取,做到解藕。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值