由于要改一些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. phpexcel--导入excel表格

    最近在做一个小项目,就是一个管理信息的小系统:要求有导入和导出的信息为excel的功能,研究过导入导出功能的肯定知道导出要比导入的简单多了,导入用的phpexcel,当时对phpexcel是完全不了解 ...

  2. java 修改类注释

    在Windows->Preferences->Java->Code Style->Code Templates 的 Comments中 Types 是控制类的注释 /** * ...

  3. Python--Day2/Day3/Day4(运算符、数据类型及内建函数)

    一.昨日内容回顾 Python种类:CPython(Python).JPython.IronPython.PyPy 编码: Unicode.UTF-8.GBK while循环 if...elif... ...

  4. tiny4412 解决内核编译版本号问题

    内核版本: linux-3.5开发板: tiny4412作者:彭东林邮箱:pengdonglin137@163.com 问题: 由于我使用 git 管理内核代码,导致编译完成后内核版本变成了如下形式: ...

  5. 【ActiveMQ】消息生产者自动注入报错:Could not autowire. No beans of 'JmsMessagingTemplate' type found

    使用ActiveMQ过程中,定义消息生产者: package com.sxd.jms.producer; import org.springframework.beans.factory.annota ...

  6. django常用第三方app大全

    djangoapp 资源大全 最近经常在这个版面看到Django相关扩展的介绍,而其一个扩展写一个帖子,觉得没太必要吧. 以前整理的django资源列表,从我的wiki上转过来的. 要找django资 ...

  7. BF3 里面的z cull reverse reload

    Bf3 siggraph2011的 分享 http://advances.realtimerendering.com/s2011/White,%20BarreBrisebois-%20Renderin ...

  8. windows8开发-关于wp7应用迁移到win8 metro风格

    虽然微软说,wp7应用移植到win8上面是比较简单,只需要修改部分API和设计原则上的细节,同时它也提供了一份比较简洁的参考文档: 而实际上这种移植的工作量还是不小的,尤其当应用引用了较多底层的API ...

  9. JAVA Eclipse开发Android程序如何自定义图标

    直接用做好的png图片替换res的所有分辨率的lc_launcher.png图片 注意到不同文件夹有不同的分辨率,直接把png图片做成最大的替换掉即可,不管小的. drawable-xxhdpi    ...

  10. STL源代码分析--第二级空间配置器

    本文解说SGI STL空间配置器的第二级配置器. 相比第一级配置器,第二级配置器多了一些机制,避免小额区块造成内存的碎片.不不过碎片的问题,配置时的额外负担也是一个大问题.由于区块越小,额外负担所占的 ...