我们在编写app的设置画面的时候自然而然地会用到Android平台提供的Preference相关组件。包括PreferenceActivity,PreferenceFragment,PreferenceCategory等。
这些组件的含义及功能都不同,适用的场景也存在区别。
接下来,我们先从官方介绍去了解这些组件。
PreferenceActivity
public abstract class PreferenceActivity
extends ListActivity implements PreferenceFragment.OnPreferenceStartFragmentCallback
上面可以看出PreferenceActivity是继承自ListActivity并实现了OnPreferenceStartFragmentCallback接口的抽象类。APP要使用这个组件的话必须继承自该类。
它有如下重要的方法。
addPreferencesFromResource() // 将需要展示的设置页面告知Activity
findPreference() // 查找指定Preference项目,方便进行后续的更新等处理
getPreferenceScreen() // 获取到当前设置页面的根布局,便于针对页面内的Preference项目进行增删改等处理
PreferenceFragment
public abstract class PreferenceFragment
extends Fragment
上面可以看出PreferenceFragment是继承自Fragment的抽象类。APP要使用这个组件的话必须继承自该类。
除了拥有PreferenceActivity的上述方法外它还有如下重要的方法。
onCreateView() // 实际上是Fragment的方法,用于将默认的ListView加载,app可以覆写该方法以达到自定义布局的目的。 onViewCreated() // 也是Fragement的方法,当app需要在ListView组件加载完做些处理的时候可以覆写该函数
Preference
public class Preference
extends Object implements Comparable<Preference>
上面可以看出Preference是直接继承自Object并实现了比较器的类。APP可以直接使用这个组件,不需要再继承。
注意
这个类直接继承自Object,并没有和View有什么继承关系,说明Preference并非View类型的控件,只是封装好了view组件的用于展示偏好设置的一种管理类。
它有如下重要的方法。
setEnabled() // 用于控制该Preference是否有效 setFragment() // 用于设置该Preference点击后跳转的目标画面的fragment类信息 setIntent() // 用于设置该Preference点击后执行的跳转intent信息 setLayoutResource() // 用于特别设置该Preference的布局,达到自定义布局的目的 setWidgetLayoutResource() // 用于特别设置Preference布局中widget插件的布局 setOnPreferenceChangeListener() // 用于设置Preference值状态变化的监听器 setOnPreferenceClickListener() // 用于设置Preference项目点击监听器 getView() // 系统将该Preference的view提取并展示前的回调,app可以自定义Preference后覆写该方法,加入view的控制逻辑达到动态更改UI的目的 PreferenceGroup
public abstract class PreferenceGroup
extends Preference
上述结构可以看出PreferenceGroup是继承自Preference的抽象类。通过提供如下方法达到嵌套Preference的目的。有点类似ViewGroup和View的关系。
public abstract class PreferenceGroup
extends Preference
上述结构可以看出PreferenceGroup是继承自Preference的抽象类。通过提供如下方法达到嵌套Preference的目的。有点类似ViewGroup和View的关系。
addPreference() // 添加Preference对象 findPreference() // 查找Preference对象 getPreference() // 根据下标取得Preference对象 removeAll() // 删除嵌套了的所有Preference对象 removePreference() // 删除指定的Preference对象
PreferenceScreen
public final class PreferenceScreen
extends PreferenceGroup implements AdapterView.OnItemClickListener, DialogInterface.OnDismissListener
上述类的结构可以看出PreferenceScreen是继承自PreferenceGroup并实现了OnItemClickListener和OnDismissListener接口的不可继承类。
注意:
拥有了PreferenceGroup赋予的嵌套Preference的功能。
是Preference页面的根标签,可以嵌套一切Preference相关组件
拥有如下重要方法
bind() // 将Preference页面以PreferenceScreen为单位和ListView控件绑定 getRootAdapter() // 获取ListView控件所创建的Adapter实例 onDismiss() // dialog消失时候的回调 onItemClick() // 在Preference项目收到click回调前ListView的回调处理
PreferenceCategory
public class PreferenceCategory
extends PreferenceGroup
PreferenceCategory是继承自PreferenceGroup的子类。
它只有一个比较重要的方法如下。
isEnabled() // 该类将默认返回false,导致该项目无法点击无法focus。App可以自定义子类并覆写该方法达到扩展的目的。
其他Preference组件
Android官方还提供了一系列Preference子类,用以满足不同场景下的偏好设置展示。有如下几个比较常用的子组件。
※后续将针对如下两种自定义类别阐述其原理。
■更改了Preference本身的布局达到自定义展示效果的子组件
CheckBoxPreference
Widget设置为CheckBox控件的Preference组件,用于展示勾选框的偏好设置。
SwitchPreference
Widget设置为Switch控件的Preference组件,用于展示开关的偏好设置。
SeekBarPreference
自定义了Preference布局内嵌了可以拖动的SeekBar的偏好设置组件。
■没有更改Preference本身布局而是更改点击后动作达到自定义展示效果的子组件
DialogPreference
点击后弹出Dialog的偏好设置。
EditTextPreference
点击后弹出自带输入框的Dialog的偏好设置。
ListPreference
点击后弹出自带ListView选择列表的Dialog的偏好设置。
Preference组件的一般结构
至此Android提供的基本组件及常用组件介绍完了。我们将上述基本组件整理概括下。
PreferenceActivity 展示设置页面的Activity,可控制多个PreferenceFragment ->PreferenceFragment 展示设置页面的Fragment(直接附着于普通Activity通过FragmentManager管理也可以) ->PreferenceScreen 设置页面的根组件 ->PreferenceCategory/PreferenceGroup 设置页面内展示标题分类的可嵌套组件 ->Preference(CheckBoxPreference…) 设置页面内展示设置条目的最小单位
常见的Preference使用示例
接下来,我们看看app最常见的使用Preference的例子。
// MyPreferenceActivity.java public class MyPreferenceActivity extends PreferenceActivity { public void onCreate(Bundle bundle) { super.onCreate(bundle); addPreferencesFromResource(R.xml.my_preference_layout); } }
<!--my_preference_layout.xml--> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:title="@string/my_preference_settings"> <PreferenceCategory android:title="@string/my_preference_general" > <Preference android:fragment="com.android.settings.applications.ManageApplications" android:key="app" android:title="@string/my_preference_general_apps" /> </PreferenceCategory> <PreferenceCategory android:title="@string/my_preference_more" > <Preference android:key="dev" android:title="@string/my_preference_more_dev"> <intent android:action="android.settings.APPLICATION_DEVELOPMENT_SETTINGS" /> </Preference> </PreferenceCategory> </PreferenceScreen>
效果图
可以看到我们没有使用任何View相关的控件,只是配置了Preference相关的组件就得到了我们想要的偏好设置页面。
接下来一节我们看下系统相关的实现原理。