一、位置
在Android的frameworks/base/core/res/res/values目录下有一下几个文件:
themes.xml
themes_device_defaults.xml
styles.xml
styles_device_defaults.xml
分别定义了各种系统Theme,Style。
二、主题
主要关注themes.xml,themes_device_defaults.xml两个文件。themes.xml定义了android低版本的theme和Holo theme,themes_device_defaults.xml定义了DeviceDefault主题(继承自Holo主题),实际上就是在Holo主题上定制主题(For厂商)。
系统如何去选择默认的主题呢?
当<11时,使用以前低版本主题;当>=11&&<14,使用Holo主题;>14的时候,使用DeviceDefault主题。
三 、系统主题Theme列表
系统默认大的主题是三种:Theme,Theme.Holo,Theme.DeviceDefault, 但是实际上在此基础系统还定义了大量的派生主题。
四、修改注意事项:
1、修改后不能影响CTS测试
2、修改文件只是厂商一个Theme,不影响原生的Theme
3、styles.xml与 themes.xml文件是不能修改的,修改后不能通过CTS测试
五、例子(我这里以switch 控件为例子):
1、这里以修改Theme.DeviceDefault主题来实现GUI公共控件的修改。这个主题就是留给厂商用来定制。如果你不修改这个主题,而是新建一个主题,那是不现实的,首先普通的开发者使用的SDK里面没有与之对应的api 接口,其次,你还要修改加载主题的相关部分。
2、原始控件的继承关系
原始的控件图:
原始的Theme.DeviceDefault里面定义switch控件的样式
由上图可看出调用的是:@android:style/Widget.DeviceDefault.CompoundButton.Switch,而这个style可以去styles_device_defaults.xml文件中找到(一般themes_device_defaults.xml
调用的style都在这个文件里)
如上图,可看出其实Widget.DeviceDefault.CompoundButton.Switch风格继承自Widget.Holo.CompoundButton.Switch,(一般styles_device_defaults.xml里面的style都继承自文件styles.xml)。
如上图,这个就是Widget.Holo.CompoundButton.Switch风格。 根据以上的调用关系,可以看出:关于Switch系统控件在Theme.DeviceDefault 主题中调用的风格最终是style.xml中的Widget.Holo.CompoundButton.Switch
3、修改方案
修改后的控件图(不会作图,就拿系统自带的图片五角星代替了):
前面我们已经说过了,styles.xml与 themes.xml 文件是不能修改的,那么问题来了,我们如何修改呢?
我们可以把style.xml中的Widget.Holo.CompoundButton.Switch 风格的所有<item>复制到styles_device_defaults.xml中的Widget.DeviceDefault.CompoundButton.Switch 中。
如下图:
然后,你就可以在这里面修改风格的属性了(<item>属性会覆盖掉parent里面的<item>属性)。
注意事项:
①、你不能把parent的属性去掉,去掉后会报异常Error retrieving parent for item: No resourcefound that matches the given name 'Widget.DeviceDefault.CompoundButton' 。造成这个异常的原因可看我的博客:
http://blog.csdn.net/daweibalang717/article/details/40738073
②、看完博客后,你就会明白,如果要把parent属性去掉的话,你就需要把Widget.DeviceDefault.CompoundButton.Switch的名字给更改了。修改成不带(.)的名字。
③、如果你要删掉一个<item>属性,那就不能覆盖父类的<item>,那么你就需要把此风格的(.)父类给继承了。比如,我要删掉
上图属性,但是如果删掉它,父类Widget.Holo.CompoundButton.Switch里面还有一条,就不能覆盖了。那么你可以把Widget.Holo.CompoundButton.Switch的(.)父类给继承了。Widget.Holo.CompoundButton.Switch的(.)父类就是Widget.Holo.CompoundButton
如下图:
④、基于第三条,不建议这么做,因为你删掉一个属性,可能造成未知异常。比如我把
文字属性去掉了。就报了空指针异常(Switch控件计算布局大小的时候用到了文字属性)。
(2)其次:
我们要修改相关属性,以达到图片效果。
android:track 属性对应的是背景布局,就是图片中灰色的部分。
android:thumb 对应的就是Switch中的五角星(修改后的样式)的部分。
android:switchTextAppearance 文本外观(修改前的样式里面带有文字 ON OFF )
android:textOn 打开时的文本(原始样式为 ON)
android:textOff 关闭时的文体 (原始样式为 OFF)
android:thumbTextPadding 这个应该是文本的距离控件周边的边距
android:switchMinWidth 控件的最小宽度
android:switchPadding 距离周边的边距
我们要把Switch控件的样子由
变成
1、要把文本给去掉。
那么就修改文本属性为:
2、把按钮变成五角星
这里要修改
属性,可以看出他调用的是资源文件drawable下的东西。路径为:\frameworks\base\core\res\res\drawable\switch_inner_holo_dark.xml
内容为:
这里才是真实调用图片的地方。那么我们能在这里修改吗?答案是不能,因为你修改这个文件的话,系统其他主题也调用的是这个文件。我们需要把此文件再复制一份,起一个新的唯一名字。我起的名字为switch_inner_holo_dark_device.xml,然后再在这个新文件里面修改调用的图片资源,
我修改成了调用小星星的资源文件。然后再修改android:thumb属性为:
3、把控件变短
因为你把控件里面的文字去掉了。方块换成了小星星,修改后控件就显的过长。那么就要把控件android:switchMinWidth 属性更改一下,我改成了原先的一半。
综上,总体改完后,styles_device_defaults.xml中的
Widget.DeviceDefault.CompoundButton.Switch"属性是这样的:
到此,这个例子修改完成。
4、测试(刷机我们修改后的OS)
你可以在eclipse里面建立一个项目,在AndroidManifest.xml文件中,把最小支持的API 设置成14
然后把Activity的Theme设置成
android:theme="@android:style/Theme.DeviceDefault"
然后在布局文件里面增加一个Switch 控件,运行APK就可以看到效果了。
修改前:
修改后: