我们在编写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的关系。
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相关的组件就得到了我们想要的偏好设置页面。
接下来一节我们看下系统相关的实现原理。