在attrs.xml声明一种属性
<attr name="
textColorHint" format="reference|color" />
|
|
在style_material.xml中引用这些attr
<style name="
TextAppearance.Material">
<item name=" textColor">?attr/textColorPrimary</item>
<item name=" textColorHint">?attr/textColorHint</item>
<item name="textColorHighlight">?attr/textColorHighlight</item>
<item name="textColorLink">?attr/textColorLink</item>
<item name="textSize">@dimen/text_size_body_1_material</item>
<item name="fontFamily">@string/font_family_body_1_material</item>
</style>
<item name=" textColor">?attr/textColorPrimary</item>
<item name=" textColorHint">?attr/textColorHint</item>
<item name="textColorHighlight">?attr/textColorHighlight</item>
<item name="textColorLink">?attr/textColorLink</item>
<item name="textSize">@dimen/text_size_body_1_material</item>
<item name="fontFamily">@string/font_family_body_1_material</item>
</style>
|
|
styles_device_defaults.xml继承style_material.xml,
<style name="
TextAppearance.DeviceDefault" parent="
TextAppearance.Material"/>
|
|
themes_device_defaults.xml定义了一组相关style
<style name="Theme.DeviceDefault" parent="Theme.Material" >
<!-- Text styles -->
<item name="textAppearance">@style/ TextAppearance.DeviceDefault</item>
<item name="textAppearanceInverse">@style/TextAppearance.DeviceDefault.Inverse</item>
<!-- Text styles -->
<item name="textAppearance">@style/ TextAppearance.DeviceDefault</item>
<item name="textAppearanceInverse">@style/TextAppearance.DeviceDefault.Inverse</item>
...
</style>
|
|
那,到底在哪赋值的呢?看parent="Theme.Material"
./themes_material.xml
<style name="Theme.Material">
...
<!-- Text styles -->
<item name="textAppearance">@style/ TextAppearance.Material</item>
<item name="textAppearanceInverse">@style/TextAppearance.Material.Inverse</item>
...
<!-- Text styles -->
<item name="textAppearance">@style/ TextAppearance.Material</item>
<item name="textAppearanceInverse">@style/TextAppearance.Material.Inverse</item>
...
</style>
|
|
在theme.xml中赋值(不同的theme赋不同的值)
<item name="textColorHint">@color/hint_foreground_dark</item>
|
|
引用的color值转成对应的16进制颜色Gray
<color name="hint_foreground_dark">#808080</color>
大致关系如下:
styles_device_defaults.xml —— themes_device_defaults.xml
|
style_material.xml —— themes_material.xml
|
style.xml —— theme.xml
几个属性attr —— 1个style
在style_material.xml中
<style name="
TextAppearance.Material">
<item name=" textColor">?attr/textColorPrimary</item> <item name=" textColorHint">?attr/textColorHint</item> <item name="textColorHighlight">?attr/textColorHighlight</item> <item name="textColorLink">?attr/textColorLink</item> <item name="textSize">@dimen/text_size_body_1_material</item> <item name="fontFamily">@string/font_family_body_1_material</item> </style> |
几个style —— 1个theme
themes_device_defaults.xml定义了一组相关style
<style name="Theme.DeviceDefault" parent="
Theme.Material" >
<!-- Text styles --> <item name="textAppearance">@style/ TextAppearance.DeviceDefault</item> <item name="textAppearanceInverse">@style/TextAppearance.DeviceDefault.Inverse</item>
...
</style>
|
2,系统控件的theme和style是怎么定义的?
以Button控件为例,使用最基本的theme.xml来分析。
在APK开发的过程,我们使用Button基本上这样使用
<
Button
android:id
=
"@+id/bt1"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_below
=
"@id/checkBox1"
android:text
=
"This is Button1"
android:textSize
=
"22sp"
/>
对应出来一个Button
Button.java这个类,在构造的时候,可以看出来是使用哪种style
public Button(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr. buttonStyle);
}
this(context, attrs, com.android.internal.R.attr. buttonStyle);
}
->
attrs.xml
<attr name="buttonStyle" format="reference" />
这是一个引用类型,那么我们看,在哪赋值?以最基本的theme.xml来分析
->
theme.xml
->
style.xml这里Widget.Button是一组属性的集合
333 <style name="Widget.Button">
334 <item name="background">@drawable/ btn_default</item>
335 <item name="focusable">true</item>
336 <item name="clickable">true</item>
337 <item name="textAppearance">?attr/textAppearanceSmallInverse</item>
338 <item name="textColor">@color/primary_text_light</item>
339 <item name="gravity">center_vertical|center_horizontal</item>
340 </style>
334 <item name="background">@drawable/ btn_default</item>
335 <item name="focusable">true</item>
336 <item name="clickable">true</item>
337 <item name="textAppearance">?attr/textAppearanceSmallInverse</item>
338 <item name="textColor">@color/primary_text_light</item>
339 <item name="gravity">center_vertical|center_horizontal</item>
340 </style>
来看一下backgroud这个属性
drawable/btn_default.xml定义了一些状态变化时候对应的属性值
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_normal_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_default_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_normal_disable_focused" />
<item
android:drawable="@drawable/btn_default_normal_disable" />
</selector>
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_normal_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_default_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_normal_disable_focused" />
<item
android:drawable="@drawable/btn_default_normal_disable" />
</selector>
3,修改默认APP主题的一些属性。
从AndroidManifest.xml可以看出当前APK使用的是哪种Theme
android:theme
=
"@style/AppTheme"
>
styles.xml
<
style
name
=
"AppBaseTheme"
parent
=
"android:Theme.Light"
>
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</
style
>
<!-- Application theme. -->
<
style
name
=
"AppTheme"
parent
=
"AppBaseTheme"
>
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</
style
>
从原始文件中可以看出,AppTheme继承自AppBaseTheme,继承自android:Theme.Light
framework/base/core/res/res/value/theme.xml
<style name="Theme.Light"> <item name="windowBackground">@drawable/screen_background_selector_light</item> <item name="windowClipToOutline">false</item> <item name="colorBackground">@color/background_light</item> <item name="colorForeground">@color/bright_foreground_light</item> <item name="colorForegroundInverse">@color/bright_foreground_light_inverse</item> ... </style> |
可以看到定义了Light主题的一些值,其实Light也是继续自Theme主题,只是Theme.Light是重写了一些sytele。
如果想要改变Theme.Light,比如说不要标题栏,
在theme主题下
<style name="Theme">
<!-- Window attributes -->
<item name="
windowNoTitle">false</item> 就是这个属性
</style>
那就生修改这个属性,修改styles.xml,注意要加上namespace即可。
<!-- Application theme. -->
<
style
name
=
"AppTheme"
parent
=
"AppBaseTheme"
>
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
<
item
name
=
"android:windowNoTitle"
>
true
</
item
> //添加这行
</
style
>
4,如果我想改一下控件的一些属性,当focus的时候,Button上面会一层浅蓝色,变成黄色。
变成
首先在theme.xml里面找Theme.Light有没有button相关的属性设置,没有。
那就找父类Theme里面Button的相关属性。其实在Button.java的构造函数可知是buttonStyle。
可以看到是引用Widget.Button 在styles.xml
<style name="Widget.Button">
<item name=" background">@drawable/ btn_default</item>
<item name="focusable">true</item>
<item name="clickable">true</item>
<item name="textAppearance">?attr/textAppearanceSmallInverse</item>
<item name="textColor">@color/primary_text_light</item>
<item name="gravity">center_vertical|center_horizontal</item>
</style>
<item name=" background">@drawable/ btn_default</item>
<item name="focusable">true</item>
<item name="clickable">true</item>
<item name="textAppearance">?attr/textAppearanceSmallInverse</item>
<item name="textColor">@color/primary_text_light</item>
<item name="gravity">center_vertical|center_horizontal</item>
</style>
背景控制的属性是btn_default
drawable/btn_default.xml里面是一个selector,是不同状态时候的Button显示
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_normal_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/ btn_default_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_normal_disable_focused" />
<item
android:drawable="@drawable/btn_default_normal_disable" />
</selector>
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_normal_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/ btn_default_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_normal_disable_focused" />
<item
android:drawable="@drawable/btn_default_normal_disable" />
</selector>
同理,把btn_default.xml复制到app项目里面的draweable下面,同时把这些.9.png图片复制到draweable-hdpi下面,如下:
再在styles.xml里面重写buttonsytle如下:
为新增部分
<!-- Application theme. -->
<
style
name
=
"AppTheme"
parent
=
"AppBaseTheme"
>
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
<
item
name
=
"android:windowNoTitle"
>
true
</
item
>
<item name= "android:buttonStyle">@style/MyWidget.Button </item>
</
style
>
<style name="MyWidget.Button" parent= "@android:style/Widget.Button" >
<item name= "android:background">@drawable/btn_default </item>
</style >
完成。