1. 问题提出:如何处理需要分屏分组的设置项?
在谷歌开发文档中以Android 3.0版本作为基线,对此问题进行不同的处理:
- Android 3.0之前:采用PreferenceScreen嵌套的方法;
- Android 3.0及之后:采用Preference Headers的方法。
2. 采用 PreferenceScreen 嵌套
采用此方法的preference.xml文件形如:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <!-- opens a subscreen of settings --> <PreferenceScreen android:key="button_voicemail_category_key" android:title="@string/voicemail" android:persistent="false"> <ListPreference android:key="button_voicemail_provider_key" android:title="@string/voicemail_provider" ... /> <!-- opens another nested subscreen --> <PreferenceScreen android:key="button_voicemail_setting_key" android:title="@string/voicemail_settings" android:persistent="false"> ... </PreferenceScreen> <RingtonePreference android:key="button_voicemail_ringtone_key" android:title="@string/voicemail_ringtone_title" android:ringtoneType="notification" ... /> ... </PreferenceScreen> ... </PreferenceScreen>
这样,所有分屏的设置说明都将集中在一个xml文件中。
3. 采用 Preference Headers
Android 3.0之后,摈弃了传统的 PreferenceScreen 嵌套方法,而是采用了所谓的 Preference Headers 方法,该方法的要点是:在主屏中通过 headers xml 文件布局列出所有的主题设置项,而每个主题设置的详细设置则由各自指定的 PreferenceFragment 负责,而各自的 PreferenceFragment 可以如传统的
PreferenceActivity 一样布局自身的 PreferenceScreen。
PreferenceActivity 一样布局自身的 PreferenceScreen。
headers xml 布局样式形如:
<?xml version="1.0" encoding="utf-8"?> <preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> <header android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentOne" android:title="@string/prefs_category_one" android:summary="@string/prefs_summ_category_one" /> <header android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentTwo" android:title="@string/prefs_category_two" android:summary="@string/prefs_summ_category_two" > <!-- key/value pairs can be included as arguments for the fragment. --> <extra android:name="someKey" android:value="someHeaderValue" /> </header> </preference-headers>
另外,为了能够显示出 headers 中的布局列表,需要在继承的 PreferenceActivity 类中实现 onBuildHeaders() 回调方法:
public class SettingsActivity extends PreferenceActivity { @Override public void onBuildHeaders(List<Header> target) { loadHeadersFromResource(R.xml.preference_headers, target); } }
4. 采用 Preference Headers 的好处
我认为采用此方法有如下优点:
- 方便同一个应用在不同屏幕大小的设备中进行适配,比如,采用 preference headers 布局之后,系统设置应用在 phone 和 pad 中的显示方式分别如下图所示:
phone 设备分屏布局
pad 设备分屏布局
- 从程序设计的角度,采用 headers 可以降低 preference 布局文件的耦合度,把原本需要写在同一个xml文件中的布局各自独立开来,各自进行控制和维护而互不影响。
- 其它优点:望高手赐教。
5. 参考
- http://developer.android.com/guide/topics/ui/settings.html
- http://developer.android.com/reference/android/preference/PreferenceActivity.html