Android设置之UI篇

一、  Android设置界面是如何定义的呢?

答:Android 系统设置的主界面是Settings.java,该类的定义为:

 

Android 类修改ui的值 安卓系统ui修改_系统设置

同时我们看看Settings.java的onCreate函数:

 

Android 类修改ui的值 安卓系统ui修改_加载_02

这里似乎没有调用setContentView的方法,那么设置的界面是如何显示的呢?那我们去它的父类(PreferenceActivity)中找找看,我们来看看这个类的onCreate方法:

 

Android 类修改ui的值 安卓系统ui修改_加载_03

正如我们看到,原来设置的界面定义为framework中的preference_list_content.xml。

通过查看preference_list_content.xml文件我们知道该布局的结构就是左右结构,左侧为一个ListView,右侧为一个PreferenceFrameLayout。

但是我们要注意的是右侧的android:visibility为gone,为什么呢?这是因为它是否显示是根据屏幕的尺寸进行适配的,如果屏幕足够大比如智能电视或者pad,就是左右结构;如果是手机,则只显示左侧的ListView,右侧内容需要单独显示。那么我们是如何判断屏幕要不要显示左右结构呢?这在PreferenceActivity.java中有函数进行判断:

 

Android 类修改ui的值 安卓系统ui修改_Android 类修改ui的值_04

也就是说是从资源文件中读取的,那我们看看这个资源文件是如何定义的呢?

 

Android 类修改ui的值 安卓系统ui修改_Android 类修改ui的值_05

也就是说PreferenceActivity去读取framework中的preference_prefer_dual_pane属性,如果返回的是true则表示是大屏设备,否则便是小屏了。

二、那么左侧列表的内容又是如何加载进去的呢?

答:在需要显示列表的时候,PreferenceActivity的onCreate会调用onBuildHeaders方法去加载列表的内容,首先Settings.java 重写了onBuildHeaders方法,方法定义如下:

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

该方法调用了PreferenceActivity.java中的loadHeadersFromResource方法,该方法就是解析xml文件,并将解析出来的header列表保存到headers中,解析的代码就省略了。那我们现在看看settings_headers.xml文件的定义。

 

Android 类修改ui的值 安卓系统ui修改_加载_06

解析并保存到headers中之后,Settings.java 调用了updateHeaderList方法对列表进行更新操作。那更新完了之后便是加载到ListView中去了,其中便用到了一个HeaderAdapter这个内部类了,这个内部类的作用就是把headers的内容加载到listView中,其中header是有4种分类的,一种是带有switch开关的(HEADER_TYPE_SWITCH比如wifi),一种是总分类的(HEADER_TYPE_CATEGORY比如更多),一种是正常的(HEADER_TYPE_NORMAL),还有一种就是按钮型的(HEADER_TYPE_BUTTON)。具体见:

 

Android 类修改ui的值 安卓系统ui修改_java_07

在Settings.java中定义了setListAdapter方法,父类在onCreate方法中调用,从而就显示了列表内容。

三、 那如何做到点击item跳转到对应的fragment的呢?

当点击listView中的item的时候,PreferenceActivity.java 中onListItemClick进行处理,

 

Android 类修改ui的值 安卓系统ui修改_系统设置_08

这个函数调用了onHeaderClick函数,

 

Android 类修改ui的值 安卓系统ui修改_android_09

这个函数针对不同的配置做不同的处理,如果是单屏也就是小屏幕的便是调用startWithFragment方法;如果是大屏幕的便调用switchToHeader函数;如果header中的fragment为null且header.intent不为空,则调用startActivity。

四、对于小屏幕的设备,点击item是如何调转到下一个界面的呢?

根据第三点我们知道,当是小屏设备时,点击item会调用startWithFragment函数,如下:

 

Android 类修改ui的值 安卓系统ui修改_加载_10

接下来看一下onBuildStartFragmentIntent的定义:

 

Android 类修改ui的值 安卓系统ui修改_Android 类修改ui的值_11

五、对于大屏幕的设备,点击item是如何调转到下一个界面的呢?

根据第三点我们知道,当是小屏设备时,点击item会调用switchToHeader(header);函数如下:

 

Android 类修改ui的值 安卓系统ui修改_android_12

结束语:

       Android系统设置的UI部分大致就学习到这里,总体来说就是界面的布局,ListView的加载,headers的解析和初始化,ListView的item点击事件。