上一节有讲到Preference的基本使用跟API的介绍 ,没有看的话请先阅读 Preference的使用(1)
现在介绍其子类PreferenceCategory 跟 PreferenceScreen,现在看下继承关系
如上图,他们都是继承自PreferenceGroup的先看一下 PreferenceGroup
PreferenceGroup 是一个Preference的集合,可以包含多个Preference,这个从字面意思不难理解
类似View 跟ViewGroup。看其API:
1.public void setOrderingAsAdded(boolean orderingAsAdded)
当一个preference被add进来的时候是否排序,如果是false的话,那么对于那些没有order的将根据里面的preference的order 跟 默认字母进行排序 。在Add一个preference的时候,是不会重新排序的,需要在add之前调用这个方法,应该要在早一点调用这个方法,这个描述好抽象。
2.public boolean isOrderingAsAdded() 当add一个preference的时候是否可以排序
3.public void addItemFromInflater(Preference preference) 被Inflater 调用增加进来
查看源码:
/** * Called by the inflater to add an item to this group. */ public void addItemFromInflater(Preference preference) { addPreference(preference); }跟第六点差不多,就是没有返回值而已
4.public int getPreferenceCount() 返回这个group中的preference的个数
5.public Preference getPreference(int index) 返回group的第index元素。
6.public boolean addPreference(Preference preference) add 一个 preference进来,但是位置跟order是有关系的,返回是否增加成功
7.public boolean removePreference(Preference preference) 从group中移除 返回是否移除成功
8.public void removeAll( ) 移除所有的
9.public Preference findPreference(CharSequence key) 根据Key来找到一个preference,没有找到就返回null
如果有个相同key的preference,那么会返回前一个preference
10.public void setEnabled(boolean enabled) group的enable ,如果false 那么这个group里面都无法响应click事件
有些方法不理解的,将在其子类中写使用代码:
现在看子类PreferenceCategory
PreferenceCategory 是一个PreferenceGroup的子类,而且是被禁用的,那么它就不可以被点击了,可以用于分类
在父类的基础上只有一个方法
public boolean isEnabled() 检测是否被enable了
PreferenceScreen 代表着preference的层次机构中的最顶层,为了显示这个类,需要一个
PreferenceActivity
指向一个实例化的PreferenceScreen。从中得之,是需要PreferenceActivity来显示的,而且是最顶层的。这个类能出现在2个地方:
1. PreferenceActivity指向它的时候,也就是PreferenceActivity调用addPreferencesFromResource的时候才被当做一个根(可以理解为布局的最外层),但是是没有显示的2.出现在Preference层次机构内部的时候, 那么它显示出来,并且是当被点击的时候会显示一个对话框形式的Preference 或者直接启动一个Intent。并且它里面的内容不会被显示 很点难理解,后面有试验代码的。官方有一个布局实例<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:key="first_preferencescreen"> <CheckBoxPreference android:key="wifi enabled" android:title="WiFi" /> <PreferenceScreen android:key="second_preferencescreen" android:title="WiFi settings"> <CheckBoxPreference android:key="prefer wifi" android:title="Prefer WiFi" /> ... other preferences here ... </PreferenceScreen> </PreferenceScreen>
现在看看这个API:
1. public ListAdapter getRootAdapter() 返回一个能被加到PreferenceActivity上显示的adapter这个Adapter的getItem会返回基本介绍已结束,现在看一下代码:Preference的子类 , 这个PreferenceScreen不会出现在在adapter中,而是出现在这个Pre
PreferenceScreen
的上面 不好理解呀2.public void bind(ListView listView) 把一个ListView跟加进来,是使得ListView 跟getRootAdapter() 绑定,并且可以点击ListView的item3.public void onDismiss(DialogInterface dialog) ,前面有说过“出现在Preference层次机构内部的时候, 那么它显示出来,并且是当被点击的时候会显示一个对话框形式的Preference” ,那么这个回调就是当那个dialog 消失的时候调用的。4.public Dialog getDialog() 得到对话框5.public void onItemClick(AdapterView parent,View view,int position,long id) 当Item被点击的时候的回调
1.理解然后在点击一个结果是:PreferenceActivity指向它的时候,也就是PreferenceActivity调用addPreferencesFromResource的时候才被当做一个根(可以理解为布局的最外层),但是是没有显示的出现在Preference层次机构内部的时候, 那么它显示出来,并且是当被点击的时候会显示一个对话框形式的Preference 或者直接启动一个Intent。并且它里面的内容不会被显示对于上面的,我们更改XML上面说顶层PreferenceScreen 是不会显示的,那么我就把它加上title等信息,在在内部创建一个PreferenceScreen 点击看其反应:XMl如下:<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:title="preference root" android:summary="preference root summary" > <Preference android:order="1" android:key="preference0" android:summary="preference0" android:title="preference" android:icon="@drawable/ic_launcher" > </Preference> <PreferenceScreen android:title="preference inside" android:summary="preference inside summary"> <Preference android:key="preference3" android:order="2" android:summary="preference3" android:title="preference3" > </Preference> <Preference android:key="preference4" android:order="2" android:summary="preference4" android:title="preference4" > </Preference> </PreferenceScreen> <Preference android:order="2" android:key="preference1" android:summary="preference1" android:dependency="preference0" android:title="preference1" > </Preference> </PreferenceScreen>结果截图:
由此可见,顶层的title跟 summary是没有显示的, 内部的PreferenceScreen是不会显示里面的子的Preference,点击才会显示出来。上面还说或者是启动一个Intent 那么就setIntent ,并把preferenceScreen加上Key ”preference screen0“
preferenceScreen = (PreferenceScreen) findPreference("preference screen0"); if (null != preferenceScreen){ preferenceScreen.setIntent(intentTest); }结果是直接启动了Intent ,没有弹出对话框,如果Intent不存在的话,点击也是不会弹出对话框,而且会报错的
如果Intent 如果不存在的话怎么来 catch呢?代码如下:
preferenceScreen.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { Log.i(TAG , "preferenceScreen is clicked "); Intent intent = preferenceScreen.getIntent(); if (null != intent){ try { startActivity(intent); } catch (Exception e) { } return true; } return false; } });思路:如果存在intent的话,那么自己启动,并且return true(事件不被传递了 ,如果intent错误也就被 catch了)
public ListAdapter getRootAdapter()
在xml中在增加一个PreferenceScreen 把screen0 中的都加入都 screen1 中
preferenceScreen = (PreferenceScreen) findPreference("preference screen 0"); preferenceScreen1 = (PreferenceScreen) findPreference("preference screen 1"); if (null != preferenceScreen){ adapter = preferenceScreen.getRootAdapter(); int count = adapter.getCount(); Log.i(TAG , "count = " + count + "is preference" + (adapter.getItem(0) instanceof Preference)); if (null != preferenceScreen1){ for (int i = 0 ; i < count ; i++){ preferenceScreen1.addPreference((Preference) adapter.getItem(i)); } } }XMl:<pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:title="preference root" android:summary="preference root summary" > <Preference android:order="1" android:key="preference0" android:summary="preference0" android:title="preference" android:icon="@drawable/ic_launcher" > </Preference> <PreferenceScreen android:title="preference inside" android:summary="preference inside summary" android:key="preference screen 0"> <Preference android:key="preference3" android:order="2" android:summary="preference3" android:title="preference3" > </Preference> <Preference android:key="preference4" android:order="2" android:summary="preference4" android:title="preference4" > </Preference> <CheckBoxPreference android:key="preference4" android:order="2" android:summary="preference4" android:title="preference4" > </CheckBoxPreference> </PreferenceScreen> <PreferenceScreen android:title="preference inside 1" android:summary="preference inside summary 1" android:key="preference screen 1"> </PreferenceScreen> <Preference android:order="2" android:key="preference1" android:summary="preference1" android:dependency="preference0" android:title="preference1" > </Preference> </PreferenceScreen>结果:
都加入进来了,但是排列刚刚相反? 这是为什么呢?
原来是 不每一个都设置了order,并且order的值都是2
为了研究这个问题,把xml改一下 ,如下:
<PreferenceScreen android:title="preference inside" android:summary="preference inside summary" android:key="preference screen 0"> <Preference android:key="preference3" android:order="2" android:summary="preference3" android:title="preference3" > </Preference> <Preference android:key="preference4" android:order="2" android:summary="preference4" android:title="preference4" > </Preference> <CheckBoxPreference android:order="2" android:key="preference5" android:summary="preference5" android:title="preference5" > </CheckBoxPreference> </PreferenceScreen> <PreferenceScreen android:title="preference inside 1" android:summary="preference inside summary 1" android:key="preference screen 1"> </PreferenceScreen>
都不加order的话那么显示结果都是 3 4 5 ,都是采用默认的排序,谁写在前面就排在前面
而当设置了order 并且都相同的时候,那么就根order来排序了
在代码中加入打印调试:
if (null != preferenceScreen1){ for (int i = 0 ; i < count ; i++){ Log.i(TAG , "key " + ((Preference) adapter.getItem(i)).getKey()); preferenceScreen1.addPreference((Preference) adapter.getItem(i)); } } 打印结果是 " 5 4 3"
然后在<span style="font-family: Tahoma, Arial;">preferenceScreen1 在</span>add的时候 是前插的 也就变成了 3 4 5
而<span style="font-family: Tahoma, Arial;">preferenceScreen0 add的时候 也就是 3 4 5 的顺序,被前插也就成了 5 4 3 </span>