官方文档

I have spent the last few days learning about how to use the new Android PreferenceFragment which requires PreferenceActivity to override a new v11 (Honeycomb) method called onBuildHeaders(). Unfortunately, the documentation is not very clear how one would create a single PreferenceActivity that could play well in all versions, utilizing the newest features if you have it and avoiding an app crash on older Android versions. I encountered several solutions to this issue by creating two different activities for the two different mechanisms requiring two entries in your AndroidManifest.xml file. Having two different PreferenceActivities means if you have library code that extends that class, you now have to duplicate it. Then, if your app descends your library class, now has to be duplicated yet again. The end result is … less than ideal.

Thankfully, after spending a great deal of time on the subject, I have come up with a single class solution that will work in all Android versions. A couple of the newer methods need to be found using reflection and based off of them, in addition to using the newly introduced xml file of , allow for a single class solution.

First, take your old xml layouts and break them up into several files based on how you would like to see them categorized using the new header format. Simply breaking them apart so that each PreferenceCategory has its own file is a good start. For our example here, we shall assume there are 3 such files, all in the res/xml folder: app_prefs_cat1.xml, app_prefs_cat2.xml, and app_prefs_cat3.xml

Now let us create the descendant PrefsActivity class:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;public class PrefsActivity extends PreferenceActivity {protected Method mLoadHeaders = null;protected Method mHasHeaders = null;/*** Checks to see if using new v11+ way of handling PrefsFragments.* @return Returns false pre-v11, else checks to see if using headers.*/public boolean isNewV11Prefs() {if (mHasHeaders!=null && mLoadHeaders!=null) {try {return (Boolean)mHasHeaders.invoke(this);} catch (IllegalArgumentException e) {} catch (IllegalAccessException e) {} catch (InvocationTargetException e) {}}return false;}@Overridepublic void onCreate(Bundle aSavedState) {//onBuildHeaders() will be called during super.onCreate()try {mLoadHeaders = getClass().getMethod("loadHeadersFromResource", int.class, List.class );mHasHeaders = getClass().getMethod("hasHeaders");} catch (NoSuchMethodException e) {}super.onCreate(aSavedState);if (!isNewV11Prefs()) {addPreferencesFromResource(R.xml.app_prefs_cat1);addPreferencesFromResource(R.xml.app_prefs_cat2);addPreferencesFromResource(R.xml.app_prefs_cat3);}}@Overridepublic void onBuildHeaders(List<Header> aTarget) {try {mLoadHeaders.invoke(this,new Object[]{R.xml.pref_headers,aTarget});} catch (IllegalArgumentException e) {} catch (IllegalAccessException e) {} catch (InvocationTargetException e) {}   }static public class PrefsFragment extends PreferenceFragment {@Overridepublic void onCreate(Bundle aSavedState) {super.onCreate(aSavedState);Context anAct = getActivity().getApplicationContext();int thePrefRes = anAct.getResources().getIdentifier(getArguments().getString("pref-resource"),"xml",anAct.getPackageName());addPreferencesFromResource(thePrefRes);}}
}

On older Android versions, the reflected methods will be null and thus avoids calling the newer methods, using the older mechanism of adding the various preference xml files in onCreate(). In order to use the new Honeycomb (v11+) preference mechanism, we need to create one more xml file – the newer <preference-headers> xml file that ties all the category files together. The res/xml resource file “pref_headers.xml”:

<?xml version="1.0" encoding="utf-8"?>
<preference-headers
    xmlns:android="http://schemas.android.com/apk/res/android" ><header android:fragment="my.domain.app.PrefsActivity$PrefsFragment"android:icon="@android:drawable/ic_menu_sort_by_size"android:title="Category 1 prefs" ><extra android:name="pref-resource" android:value="app_prefs_cat1" />
</header>        <header android:fragment="my.domain.app.PrefsActivity$PrefsFragment"android:icon="@android:drawable/ic_menu_gallery"android:title="Category 2 prefs" ><extra android:name="pref-resource" android:value="app_prefs_cat2" />
</header><header android:fragment="my.domain.app.PrefsActivity$PrefsFragment"android:icon="@android:drawable/ic_menu_edit"android:title="Category 3 prefs" ><extra android:name="pref-resource" android:value="app_prefs_cat3" />
</header><header
    android:icon="@drawable/icon_question"android:title="Blackmoon Info Tech Services"android:summary="link to BITS blog"><intent android:action="android.intent.action.VIEW"android:data="http://www.blackmoonit.com/2012/07/all_api_prefsactivity/" />
</header></preference-headers>

The first three headers list the three standard category xml files we created, but you are also free to add more items as you see fit, just remember that those will only be visible on devices with Android 3.0 or later.

Now that we have our xml file and single preference activity, we can define it in our AndroidManifest.xml as usual. Note: do not use android:launchMode=”singleTop” for your prefs activity or else it will break phones using 4.0+ by never showing more than just the header list.

<activity android:name="PrefsActivity"android:label="Settings"android:enabled="true" ><intent-filter><category android:name="android.intent.category.PREFERENCE" /></intent-filter></activity>

We can have a menu call our prefs activity with just one line:

startActivity(new Intent(this, PrefsActivity.class);

Now that you have a descendant class like this one, you can freely use it in all versions of Android and it will automatically use the newer mechanism where appropriate.

查看这里

Android’s PreferenceActivity for all API versions相关推荐

  1. Android 9.0 功能和 API概览(中文版)

    Android 9 功能和 API 官方搬运: Android 9(API 级别 28)为用户和开发者引入了众多新特性和新功能. 本文重点介绍面向开发者的新功能. 要了解新 API,请阅读 API 差 ...

  2. android版本号和对应的API等级

    随着版本的更迭,应用程序编程接口(API)等级不断发生.下面将目前为止所有API等级罗列出来,并与Android各版本一一对应. API等级1:Android 1.0 API等级2:Android 1 ...

  3. 使用内部(com.android.internal)和隐藏(@hide)API手记

    使用内部(com.android.internal)和隐藏(@hide)API手记 内部API和隐藏API的不同 隐藏API隐藏是为了防止开发人员使用SDK中未完成或者未稳定(接口和架构方面看)的部分 ...

  4. Android 11 新特性和API兼容

    这个文档主要产品层面,新的特性..兄弟blog,Android11的Api变化和迁移变化. 1,新特性 1.1,设备控件 Android 11 包含一个新的 ControlsProviderServi ...

  5. Android平台所支持的API级别

    大家好:与人奋斗,其乐无穷!衷心希望各位坚守本心,实现中华民族伟大复兴的中国梦! 一.什么是API级别? API级别是对Android平台提供的框架API版本进行唯一标识的整数值. Android 平 ...

  6. Android开发者编写自己的API接口(下)

    前言 在上一篇Android开发者编写自己的API接口(上)中,已经介绍了如何搭建一个基本的开发环境,以及接口的编写,最后是能够成功运行的. 这一篇将更进一步,主要解决下面两个问题: ①:如何让后台项 ...

  7. xbox android,Android 上的 Xbox Live Api 入门

    Android 上的 Xbox Live Api 入门 09/21/2018 本文内容 若要将 Xbox Live Api 用于 Android 游戏,你可以使用预编译的二进制文件,或在你的项目中包含 ...

  8. android语音识别之科大讯飞话音API的使用

    android语音识别之科大讯飞语音API的使用 布局文件: <?xml version="1.0" encoding="utf-8"?> < ...

  9. Android 8.0 功能和API -翻译

    用户体验 通知 在 Android 8.0 中,我们已重新设计通知,以便为管理通知行为和设置提供更轻松和更统一的方式.这些变更包括: 通知渠道:Android 8.0 引入了通知渠道,其允许您为要显示 ...

最新文章

  1. sscanf用法(转)
  2. jdk1.7 hashmap多线程下的死循环
  3. Javascript 逗号“,”引发的血案
  4. 2019招商银行M-Geeker线上比赛题解析
  5. MVC应用程序显示RealPlayer(rm)视频
  6. 越狱解决iphone4s外放无声音
  7. PHP错误日志记录:display_errors与log_errors的区别
  8. Atitit 图像处理知识点  知识体系 知识图谱
  9. python 文本处理---英文文本预处理(简单易懂 全有注释)!!!!!使用正则表达式以及nltk库分词器双方法!
  10. iptv服务器制作 php,DIY点播服务器
  11. 安卓坐标系转换之二:旋转角(欧拉角)
  12. 音高和频率转换(转载)
  13. GNURadio3.9.4创建OOT模块实例
  14. 百度ueditor富文本--配置图片上传
  15. 考计算机二级需要学哪些,考计算机二级需要学哪些内容
  16. ubuntu简繁体输入法快捷键转换
  17. LED点阵-第1季第8部分-朱有鹏-专题视频课程
  18. 夏至日环食奇趣天象将在中国天空上演 错过再等十年
  19. 什么时候建立数据库,怎么建立数据库?
  20. MYSQL:查询年龄最大的5个学生(包括年龄并列第5名的所有学生)的姓名、年龄及所在系。

热门文章

  1. python sin(x)/x 图像
  2. pyspark pipline
  3. 合并两个有序的单链表
  4. 机器学习笔记 时间序列预测(最基本的方法【benchmark】)
  5. PyTorch笔记: GPU上训练的模型加载到CPU/错误处理Attempting to deserialize object on a CUDA device but torch.cuda.is_a
  6. 算法整理:Boyer-Moore 投票算法
  7. 深度学习核心技术精讲100篇(三十)-ClickHouse在字节跳动广告业务中的应用
  8. Java调用Matlab
  9. matlab 最后一列,求大神帮我解释一下matlab最后几行是什么意思
  10. 【Linux】13_ 文件查找