2024年3月7日发(作者:)
Android进阶——Preference详解之Preference系的基本应用和管理(二)
一、PreferenceActivity
1、PreferenceActivity概述
PreferenceActivity是一个抽象类,继承于ListActivity,以列表形式视图来展现界面,加载的整个View也是基于ListActivity中那个ListView的,其最主要的优势在于添加Preference后可让其状态持久化储存(通过SharedPreferences,一般存储在/data/data//shared_prefs文件夹下的默认名为“app package name”+”_”的文件里),比如说用户勾选CheckBox后退出应用,下一次进入到这一界面时候,对应的是CheckBox依然是被勾选状态,如果要实现这样的机制,我们自己也可以实现,但是没有必要,因为Android已经替我们实现了,就是我们的这一系列的主角——Preference,Preference会自动地替我们去保存这些状态对应的值到对应的SharedPreferences文件里,而当我们每次启动的时候Acitivity(PreferenceActivity)会自动根据key去获取相关数据,完成用户界面的更新。我们手机当中的系统设置就是及其典型的Preference的应用,也正是由于工作中需要去客制化Settings,才有了这一系列的文章。
上图是我们定制的Settings模块中的对应的部分SharedPreferences。关于Preference对应的SharedPreferences往往很容易被我们忽视两点
并非我们第一次打开相应界面之后就会自动创建对应的SharedPreferences文件,而是在我们改变了原有状态时候
并非所有的Preference及其子类都会创建,仅仅针对需要记录状态的Preference。
2、PreferenceActivity的初始化
PreferenceActivity其实和普通的Activity本质上来说区别不大,只不过多了些自动去读取SharedPrefrences的值来更新界面和其他一些逻辑,所以初始化本质上来说并无很大的区别,但是与普通Activity的layout不同,PreferenceActivity的layout我们可以理解成为两个部分:其他View和一个id为的ListView,那么我们可以理解成为当我们在onCreate方法里先调用setContentView完成整个Activity的View的构建(layout文件里必须包含id为的listView,否则会报E/AndroidRuntime: Caused by:
eException: Your content must have a ListView whose id attribute is
‘’),再调用addPreferencesFromResource来完成Preference界面的构建;当然也可以只调用addPreferencesFromResource方法。
1、继承PreferenceActivity实现具体业务类,重写相关生命周期方法
public class MainActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
te(savedInstanceState);
setContentView(ty_main);
addPreferencesFromResource(_preference);
}
...
}
2、通过addPreferencesFromResource(xml资源id)加载静态xml资源文件 或者 完全通过代码构造对象再动态添加
在res文件夹下新建xml文件夹,再在xml文件中新建对应的xml资源,xml资源类似我们在使用普通Activity时的layout文件,PreferenceActivity独特之处在于并不是使用普通的layout文件,而是使用res下xml文件夹下的xml资源文件
res/xml/demo_
android:key="key_checkbox_preference" android:summary="Some summay for CheckBoxPreference" android:title="The Title Of CheckBoxPreference" /> 也可通过代码去构造对象,添加容器之后再调用setPreferenceScreen(PreferenceScreen preferenceScreen)把容器对象设置到Activity上 private void createPreference(){ PreferenceScreen preferenceScreen = ferenceManager().createPreferenceScreen(this);//先构建PreferenceScreen对象得到一个布局容器 ferenceScreen(preferenceScreen);//设置容器 CheckBoxPreference checkBoxPreference=new CheckBoxPreference(this);//构建一个子Preference,待添加到容器中 (CHECKBOXPRERENCE_KEY);//设置key le("The Title Of CheckBoxPreference");//设置title mary("Some summay for CheckBoxPreference"); ference(checkBoxPreference);//添加到容器中 } 二、Preference的使用 前一篇文章我们讲述了Preference家族的基类(接下来我们所要介绍的其他子类Preference一定是继承了他的所有属性也可以理解成都是在继承他所展示的UI效果及交互功能的基础上升级的)而且Preference可以实例化,那么我们就可以把他看成对应的一个组件,其实和我们熟悉的TextView一样,所以我们需要使用的时候第一步肯定是先得到他的对象——而构造对象我们都可以通过两种方式:通过其对应的构造方法或者其他方法和通过xml映射(或许说法不够准确),接着第二步PreferenceActivity的初始化,再接着根据业务设置相关监听。 1、 构造Preference容器和Preference对象 而构造对象我们都可以通过两种方式:通过其对应的构造方法或者其他方法和通过映射xml(或者讲法不够准确)。 res/xml/test_ android:key="using_categories_in_root_screen" android:summary="Using Preference Categories" android:title="Categories"> android:key="key_prerence" android:title="Preferece" android:summary="Preference Demo" /> 2、初始化PreferenceActivity和设置相关监听 常见的Preference的事件有两个:setOnPreferenceClickListener和onPreferenceChange 设置Preference点击监听 referenceClickListener(new erenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { //当接收到Click事件之后触发 return true; } }); 设置Preference对应的SharedPrefernces值监听 referenceChangeListener(new erenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { //如果值改变了我们可以通过监听这个事件来处理 return true; } }); @Override protected void onCreate(Bundle savedInstanceState) { te(savedInstanceState); setContentView(ty_main);//activity_main里必须存在id为的ListView否则报E/AndroidRuntime: Caused by: eException: Your content must have a ListView whose id attribute is '' addPreferencesFromResource(_preference); mContext=getApplicationContext(); preference=findPreference(PREFERENCE_KEY); referenceChangeListener(new erenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { //如果值改变了我们可以通过监听这个事件来获取新值 xt(mContext, ("Preference的值为%s", newValue),_LONG).show(); return true; } }); //设置Preference的点击事件监听 referenceClickListener(new erenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { //当接收到Click事件之后触发 xt(mContext, "Preference Clicked",_LONG).show(); return true; } }); } android:title="PreferenceScreen"> android:key="key_prerence" android:summary="Preference Categories Summary" android:title="Preference Categories"> android:icon="@mipmap/ic_launcher" android:key="key_chkpreference" android:title="CheckBoxPreferenceCheckBoxPreferenceCheckBoxPreferenceCheckBoxPreference" android:summary="CheckboxPreference summary"/> android:title="Preference" android:key="key_pre" android:icon="@mipmap/ic_red_launcher" android:layout="@layout/activity_main" /> android:icon="@mipmap/ic_blue_launcher" android:key="key_edtkpreference" android:title="EditPreference" android:summary="EditPreference summary" /> 4、Preference的xml文件中的常用标签intent、extra 在xml文件的Preference标签中,我们可以添加intent来为我们快速实现一种意图,比如说快速打开一个网页,或者快速启动一个Activity等等,还可以使用extra给intent标签加参数来传递参数(再通过getIntent().getStringExtra(“key”)来获取)。 android:title="Click me open the web" android:key="key_pref_intent" > android:data=""/> android:name="key" android:value="value"/> 启动指定类 android:title="PREFERENCE TITLE" > android:action="ACTION_A_INTENT" android:targetPackage="ng" android:targetClass="tivity"> 三、PreferenceScreen和PreferenceCategory PreferenceScreen和PreferenceCategory没有新增的属性,所有属性全部继承自Preference。其中PreferenceScreen作为顶级容器,PreferenceCategory作为次级容器(类似于SQL Group by功能暂且这么理解吧),虽然他们也是可以单独使用的,但是并不能响应onPreferenceClick和onPreferenceChange事件。 布局和MainActivity的代码依然很简单和前面类似 android:title="PreferenceScreen"> android:key="key_prerence" android:summary="Preference Categories Summary" android:title="Preference Categories"> android:title="PreferenceScreen"> android:key="key_prerence" android:summary="Preference Categories Summary" android:title="Preference Categories"> android:icon="@mipmap/ic_launcher" android:key="key_chkpreference" android:title="CheckBoxPreference" android:summary="CheckboxPreference summary"/> android:icon="@mipmap/ic_blue_launcher" android:key="key_edtkpreference" android:title="EditPreference" android:summary="EditPreference summary" /> 四、RingtonePreference的应用 RingtonePreference起作用就是供我们选择系统铃声的,除了Preference共有的属性外还新增了自己的几个独特属性。 应用也很简单,与Preference大同小异(注意看图) android:key="using_categories_in_root_screen" android:summary="Using Preference Categories" android:title="gories"> android:key="key_prerence" android:title="RingPreferece Title" android:summary="RingPreference Summary" /> 五、Preference的管理 Preference的管理主要包含Preference的创建、添加、移除和寻找特定Preference,Preference并没有直接提供相关替换的方法。 1、创建Preference 主要是通过各自对应Preference的构造方法或者直接在xml文件中定义来创建对应的Preference 2、addPreference添加Preference 添加只要是就是调用PreferenceGroup的addPreference(Preference preference)方法 来添加至容器PreferenceGroup。 3、findPreference寻找特定Preference 对于PreferenceActivity的findPreference(key)方法,我们只需要知道key值就可以找到同一xml文件下相应的Preference,勿需考虑层级和嵌套关系 4、removePreference或removeAll移除Preference 对于PreferenceGroup的removePreference(Preference preference)和removeAll()方法,都是针对某个PreferenceGroup来处理的,所以我们必须考虑层级嵌套关系,可以分为两步:先找到PreferenceGroup和要删除的Preference,再调用PreferenceGroup的removePreference执行删除动作。 首先这是我们的布局 android:key="key_manage_prefs"> android:key="key_category" android:title="PreferenceCategory"> android:key="key_edtprefs" android:title="EditTextPreference" /> android:key="key_child_prefscreen" android:title="Child PreferenceScreen"> android:key="key_checkbox" android:title="CheckBoxPreference" /> 测试主体代码 public class MainActivity extends PreferenceActivity { private Context mContext; private Preference preference; @Override protected void onCreate(Bundle savedInstanceState) { te(savedInstanceState); addPreferencesFromResource(_preference); //removePreferenceByKey(); mContext=getApplicationContext(); =findPreference("key_checkbox_child");//只要是同一个xml文件下的所有Preference都能通过key直接找到 referenceChangeListener(new erenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { xt(mContext, ("Preference的值为%s", newValue),_LONG).show(); return true; } }); referenceClickListener(new erenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { xt(mContext, "Preference Clicked",_LONG).show(); //getFragmentManager().beginTransaction().replace(t,new MainFragment()).commit(); return false; } }); } private void removePreferenceByKey(){ /*PreferenceGroup preferenceGroup=(PreferenceGroup)findPreference("key_category");//先找到PreferenceGroup Preference preference=findPreference("key_edtprefs");//再找到要删除的Preference*/ /*(PreferenceGroup)findPreference("key_child_prefscreen").removePreference(findPreference("key_checkbox_child"));//执行删除key为key_checkbox_child的Preference**/ getPreferenceScreen().removePreference(findPreference("key_category"));//删除掉key_category及对应节点下的所有节点 //ERROR//getPreferenceScreen().removePreference(findPreference("key_edtprefs"));//无效,因为getPreferenceScreen获得的是当前的顶级容器,而key_edtprefs不是它的直接字节点 ////((PreferenceGroup)findPreference("key_category")).removeAll();//仅删除掉key_category下对应Preference节点下的所有子节点 } 小结 这篇文章主要介绍了Preference家族树中顶级成员和次级成员的应用和简单原理的说明,也基本把几乎所有相关的知识点都涉及了,Preference的基本语法都是一样的,区别在于各自不同的特性。
发布评论