菜鸟Android4.0 Settings分析(一)

时间:2022-08-08 00:03:09

先声明:本人工作半年,是真的菜鸟,之前有做过2.3的Launcher,没有记录下来,感觉挺可惜的,现在老大叫我搞Setting,我觉得是得写得东西,记录下自己的工作。设备都还没到,现在只能看看代码,就先记录下看代码的收获吧。。


注意:Fragment是android3.0以上才支持的,3.0之前得导jar包,我在找Setting里面ListView的item的click事件时找了好久,因为之前关联的是2.3的源码,当我跳到PreferenceActivity类里面想看下Header类里,一直找不到(sb了),最后到官方的Reference上去找才想起来自己的源码关联的是2.3的(真的sb了...)。。。

Settings的包结构:

菜鸟Android4.0 Settings分析(一)

 一、Setting的主界面

public class Settings extends PreferenceActivity implements ButtonBarHandler

1、布局
4.0的Setting是采用PreferenceFragment的形式进行布局的。

它的布局文件是xml文件夹下的:settings_headers.xml

这个布局文件下面全是<Header></Header>标签,e.g:
<header android:title="@string/header_category_wireless_networks" />
这个代表的界面就是:

设置界面最上面的一个分类(category)

2、com.android.settings.Settings.java主activity

实现onBuildHeaders()回调用来指定头文件,即加载界面对应的Fragment
调用loadHeadersFromResource()方法对界面进行加载
@Override
public void onBuildHeaders(List<Header> headers) {
loadHeadersFromResource(R.xml.settings_headers, headers);
updateHeaderList(headers);
mHeaders = headers;
}

Ctrl+T查看下Settings的继承关系
Settings-->PreferenceActivity-->ListActivity-->Activity-->xxx
可以看到Settings是ListActivity的一个后代,可知Setting主界面的项都是放在一个ListView里面的
查看一下Settings的代码发现:
 
 
@Override    public void setListAdapter(ListAdapter adapter) {    	if (mHeaders == null) {    		mHeaders = new ArrayList<Header>();    		// When the saved state provides the list of headers, onBuildHeaders is not called    		// Copy the list of Headers from the adapter, preserving their order    		for (int i = 0; i < adapter.getCount(); i++) {    			mHeaders.add((Header) adapter.getItem(i));    		}    	}    	// Ignore the adapter provided by PreferenceActivity and substitute ours instead    	super.setListAdapter(new HeaderAdapter(this, mHeaders));    }


 
 
 
 
 
 
 

所以这个才是显示界面的地方。其中HeaderAdapter是Settings中的一个内部类。下面来看下HeaderAdapter这个适配类
private static class HeaderAdapter extends ArrayAdapter<Header> {
//三种 类型的header
static final int HEADER_TYPE_CATEGORY = 0;//分类
static final int HEADER_TYPE_NORMAL = 1;//一般的
static final int HEADER_TYPE_SWITCH = 2;//开关形式的
....
}

类的开头就定义了三个常量:这个代表Header的三种类型
HEADER_TYPE_CATEGORY代表一个分类,它不能点击,像这个:

HEADER_TYPE_NORMAL代表一个常规项,像这个:

HEADER_TYPE_SWITCH代表一种开头形式的类型,像这个:

getView()方法中也是根据三种不同的类型,加载不同的view以及数据。

显示基本上就这样了,下面就是事件的响应了,点击一个item后的响应。查看一下PreferenceActivity的源码,可以看到PreferenceActivity重写了ListActivity的这个文法
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
if (mAdapter != null) {
Object item = mAdapter.getItem(position);
if (item instanceof Header) onHeaderClick((Header) item, position);
}
}

再看onHeaderClick()方法
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);
}
}


今天就到这里,明天继续。。。。