由于要改一些settings里面的bug以及之前在里面有做过勿扰模式,准备对勿扰模式做一个总结,那先分析一下settings的源代码,里面的核心应该就是android3.0
上面的首选项框架PreferenceFragment。

由于在3.0之前都是把这些东西放在PreferenceActivity的,可是3.0之后google建议把setting放在PreferenceFragment,可是PreferenceActivity也同一时候在用的,以下就此总结一下:

PreferenceActivity的作用是管理全部headers,而每个header相应一个PreferenceFragment,相应不同的设置种类界面所以我感觉PreferenceActivity偏向系统级的设置,就比方android系统的settings。对于一些简单的应用设置一个PreferenceFragment是能够搞定的。

我们自己定义一个
activity extends PreferenceActivity必须重写onBuildHeaders()这个方法,在这里载入一个xml布局显示:

@Override
public void onBuildHeaders(List<Header> target) {
// TODO Auto-generated method stub
loadHeadersFromResource(R.xml.activity_headers, target);
}

自己写一个xml文件看下。R.xml.activity_headers:

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android" >
<header
android:id="@+id/wifi"
android:title="wifi"
android:icon="@drawable/ic_launcher"
android:fragment="com.example.preferencefragmenttest.WifiFragment"/> <header
android:id="@+id/net"
android:title="移动网络"
android:icon="@drawable/ic_launcher"
android:fragment="com.example.preferencefragmenttest.NetFragment"/> <header
android:id="@+id/ee"
android:title="打开activity"
android:icon="@drawable/ic_launcher"
>
<intent android:action="android.intent.action.NEW"></intent>
</header>
</preference-headers>

每个header点击就会进入一个新的界面。有两种情况:要么是fragment要么是intent打开一个activity。先看看源代码了解这里的原理,为什么点击就会进入对应界面。找到父类PreferenceActivity有个方法:

public void onHeaderClick(Header header, int position) {
if (header.fragment != null) {
if (mSinglePane) {
int titleRes = header.breadCrumbTitleRes;
int shortTitleRes = header.breadCrumbShortTitleRes;
if (titleRes == 0) {
titleRes = header.titleRes;
shortTitleRes = 0;
}
startWithFragment(header.fragment, header.fragmentArguments, null, 0,
titleRes, shortTitleRes);
} else {
switchToHeader(header);
}
} else if (header.intent != null) {
startActivity(header.intent);
}
}

非常明显能够看出它推断了header相应fragment和activity的两种情况,打开activity这个好理解。看看fragment是怎么打开的,进入switchToHeader(),再进去switchToHeaderInner():

private void switchToHeaderInner(String fragmentName, Bundle args, int direction) {
getFragmentManager().popBackStack(BACK_STACK_PREFS,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
if (!isValidFragment(fragmentName)) {
throw new IllegalArgumentException("Invalid fragment for this activity: "
+ fragmentName);
}
Fragment f = Fragment.instantiate(this, fragmentName, args);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.replace(com.android.internal.R.id.prefs, f);
transaction.commitAllowingStateLoss();
}

非常明白的知道这个跳转的fragment被装载在当前的activity了。也是告诉我们不须要再new 自己的activity来装这个fragment,我们仅仅须要在header里面写好fragment的属性。

那么为啥有的header还是用intent指定activity呢。我分析是由于有些系统界面须要别的应用直接intent訪问。比方WIFI设置界面:

startActivity(new Intent( android.provider.Settings.ACTION_WIRELESS_SETTINGS)); 

那当然须要想自己再建一个activity了,接着就是PreferenceFragment的使用方法,也是自己定义fragment extends
PreferenceFragment,而且载入xml布局:

@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.wifi_preference);
}

看一下这个布局。简单的写几个系统自带的preference:

<?

xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="isopen"
android:title="wifi"
android:defaultValue="true"/>
<ListPreference
android:key="list"
android:title="声音大小"
android:entries="@array/keys"
android:entryValues="@array/values"/>
<Preference
android:key="click"
android:title="单独的"
/> </PreferenceScreen>

还能够在里面增加PreferenceCategory标签,作用是分块吧,中间间隔略微大一些,区分同一页面不同设置类别

<PreferenceCategory >
<cn.com.demo.ota.MyButtonPreference
android:key="start_install"
android:title="@string/update_install"/>
</PreferenceCategory>

PreferenceFragment里面有个方法onPreferenceTreeClick()能够重写。可是依照上面的布局发现此方法不起作用。看下这种方法源代码:

 /**
* {@inheritDoc}
*/
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) {
if (preference.getFragment() != null &&
getActivity() instanceof OnPreferenceStartFragmentCallback) {
return ((OnPreferenceStartFragmentCallback)getActivity()).onPreferenceStartFragment(
this, preference);
}
return false;
}

看的出来,必需要这个被点击的preference含有相应的fragment。否则返回false点击不起作用。那么一般我们用

update_more = (Preference)findPreference("update_more");<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">

</span></span></span><pre name="code" class="java">update_more.setOnPreferenceClickListener(new OnPreferenceClickListener() {

				@Override
public boolean onPreferenceClick(Preference preference) { }
});


来设置preference的点击事件,最后一点怎么得到我们保存的数值呢?在该应用的文件夹下能够找到 包名_preference.xml的文件,里面就是我们保存的数值 调用getDefaultSharedPreferences就能够拿到这个的SharedPreferences对象从而取到数值。

当然上面说的都是最基础的使用方法。看settings的源码里面的preference都是自定义的,用listview显示不同类型的preference,并且看Settings.java的一个方法:

/**
* Populate the activity with the top-level headers.
*/
@Override
public void onBuildHeaders(List<Header> headers) {
loadHeadersFromResource(R.xml.iradar_settings_headers, headers);
updateHeaderList(headers);
}

在载入完xml文件后还调用了uodateHeadersList(headers)这里事实上就是一个动态更新,不同系统版本号用户权限不一样,呈现出来的设置界面也不一样。

首选项框架PreferenceFragment部分源代码分析的更多相关文章

  1. 详解Android首选项框架ListPreference

    详解Android首选项框架ListPreference 原文地址 探索首选项框架 在深入探讨Android的首选项框架之前,首先构想一个需要使用首选项的场景,然后分析如何实现这一场景.假设你正在编写 ...

  2. 转:Android preference首选项框架

    详解Android首选项框架ListPreference 探索首选项框架 在 深入探讨Android的首选项框架之前,首先构想一个需要使用首选项的场景,然后分析如何实现这一场景.假设你正在编写一个应用 ...

  3. 详解Android首选项框架的使用

    首选项这个名词对于熟悉Android的朋友们一定不会感到陌生,它经常用来设置软件的运行参数. Android提供了一种健壮并且灵活的框架来处理首选项.它提供了简单的API来隐藏首选项的读取和持久化,并 ...

  4. Android应用程序框架层和系统运行库层日志系统源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6598703 在开发Android应用程序时,少 ...

  5. UiAutomator源代码分析之UiAutomatorBridge框架

    上一篇文章<UIAutomator源代码分析之启动和执行>我们描写叙述了uitautomator从命令行执行到载入測试用例执行測试的整个流程.过程中我们也描写叙述了UiAutomatorB ...

  6. Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6642463 在前面几篇文章中,我们详细介绍了A ...

  7. 【Android开源项目分析】android轻量级开源缓存框架——ASimpleCache(ACache)源代码分析

    转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46379055 ASimpleCache框架源代码链接 https://github ...

  8. Android异步任务处理框架AsyncTask源代码分析

    [转载请注明出处:http://blog.csdn.net/feiduclear_up CSDN 废墟的树] 引言 在平时项目开发中难免会遇到异步耗时的任务(比方最常见的网络请求).遇到这样的问题.我 ...

  9. Hadoop源代码分析

    http://wenku.baidu.com/link?url=R-QoZXhc918qoO0BX6eXI9_uPU75whF62vFFUBIR-7c5XAYUVxDRX5Rs6QZR9hrBnUdM ...

随机推荐

  1. Python学习杂记_10_三元运算符

    常用三元运算符来简化分支和循环的代码: 分支简化: a = 1b = 2c = a if a > 1 else bprint(c) # 以上几行等同于 a = 1b = 2if a >1: ...

  2. 网络编程socket-SocketServer-FTP

    16章 网络编程?应该是讲网络之间如何编程来进行通信的章节 16.1.1 客户端/服务器架构?客户端请求访问,服务器端监听请求,处理请求,进行相应的模式16.1.2 客户端/服务器编程?服务器端:创建 ...

  3. hdu 2685(数论相关定理+欧几里德定理+快速取模)

    I won't tell you this is about number theory Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: ...

  4. springBoot AOP环绕增强、自定义注解、log4j2、MDC

    (一)log4j2 maven配置 <dependency> <groupId>org.springframework.boot</groupId> <art ...

  5. eclipse主题样式

    Eclipse Color Themeshttp://eclipsecolorthemes.org/ Get it Download from Eclipse Marketplace Install ...

  6. Android修改包名的方法,简单粗暴。

    几分钟之内,简单粗暴的修改包名! 序:Android的新手玩家可能对修改包名这件事情很是烦恼,我这里给出一个最快的修改包名的方法,简单粗暴,喜欢的可以收藏一下. 开始修改 第一步:修改自己app mo ...

  7. android 集成友盟分享之后,想自定义分享面板的看过来

    第一种情况 首先上传一张默认的友盟分享的效果图 看起来还不错,但是总是有这样那样的原因,需要我们对默认效果做出一些改变. 第二种情况 如果你想做出下面的效果: 或者这样的效果 : 总之上面的效果总是在 ...

  8. 长安大学第四届“迎新杯”程序设计竞赛 F 打铁的箱子【数学/进制思维/折半枚举】

    题目描述 作为彩虹岛上最擅长打铁的人,

  9. BZOJ1088(SCOI2005)

    枚举第一行第一个格子的状态(有雷或者无雷,0或1),然后根据第一个格子推出后面所有格子的状态.推出之后判断解是否可行即可. #include <bits/stdc++.h> using n ...

  10. Ceres Solver: 高效的非线性优化库(一)

    Ceres Solver: 高效的非线性优化库(一) 注:本文基于Ceres官方文档,大部分由英文翻译而来.可作为非官方参考文档. 简介 Ceres,原意是谷神星,是发现不久的一颗轨道在木星和火星之间 ...