概述
Android Attr、Style和Theme 在我们的开发过程中经常打交道,UI 风格的多样化全靠它们来完成,本文对它们做一个简单的介绍。
概念说明
- Attr:属性,风格样式的最小单元,比如TextView 的字体颜色
android:textColor
。 - Style:风格,它是一系列Attr的集合用以定义一个 View 的样式,比如height、width、padding等;
- Theme:主题,它与Style作用一样,不同于Style作用于个一个单独View,而它是作用于Activity上或是整个应用。
属性
我们为 View 设置的每一个属性,在系统中都有相对应的定义,包括我们自定义的属性,也需要为其声明一下。
比如,我们设置 View 的宽度,使用 layout_width
,那么在系统中声明的属性值如下:
1 | <declare-styleable name="ViewGroup_Layout"> |
对应了三个枚举值。
关于自定义属性以及属性更加详细的说明,参考我的博客Android – 自定义Attribute和Styl
风格
style 其实就是一个属性的集合,把View的不同的属性结合在一起,就形成了一个统一的风格。
首先在 style.xml 中定义一个 style:
1 | <style name="customText"> |
然后在布局文件中使用。
主题
Theme与Style使用同一个元素标签 <style>
,区别在于所包含的属性不同,并且使用的地方也不一样。Theme你需要设置到AndroidManifest.xml的 <application>
或者 <activity>
标签下,设置后,被设置的 Activity 或整个应用下所有的 View 都可以使用该 <style>
里面的属性了。
属性优先级
我们先来做一个测试,
先为 Activity 设置一个布局文件:
1 | <?xml version="1.0" encoding="utf-8"?> |
先在 style.xml 文件中为 application 定义一个主题:
1 | <style name="TestAppTheme" parent="Theme.AppCompat"> |
在 AndroidManifest.xml 中设置:
1 | <application |
打开 Activity,字体颜色和大小和我们配置的相同。
接下来为 Activity 设置主题:
1 | <style name="TestActivityTheme" parent="Theme.AppCompat"> |
在 AndroidManifest.xml 中设置:
1 | <activity android:name=".attr.AttrActivity" |
这时 TextView 的表现和 TestActivityTheme 相同,那么就表示,Activity 主题中的属性会覆盖掉 Application 中的主题中的属性值。
接下来为 TextView 设置 style:
1 | <style name="customText"> |
1 | <TextView |
这时 TextView 的表现就是 customText 设置的值了。
接下来在布局文件中为 TextView 设置属性。
1 | <TextView |
这时 TextView 的颜色值是在布局文件中设置的颜色值。
综上,我们可以得到结论:Androd 使用属性的顺序为:布局文件中设置的值 > View style > Activity theme > Application theme。
获取 Attr
有些情况下,我们可能需要使用 theme 中的属性值,比如下面我们想让一个 TextView 直接显示我们在 theme 中定义的颜色,则可以如下做:
先在 attr.xml 中自定义一个属性组:
1 | <declare-styleable name="myCustomStyle"> |
然后把在主题中为该属性设置一个颜色值:
1 | <style name="TestActivityTheme" parent="Theme.AppCompat"> |
那么我们可以再 TextView 中使用:
1 | <TextView |
Attr 的使用格式是:
1 | ?[*<package_name>*:][*<resource_type>*/]*<resource_name>* |
如果是本应用中的attr使用,则可以省去<package_name>部分。
如果想要使用系统的属性值:
1 | android:textColor="?android:textColorSecondary" |
此处的 textColor 使用当前主题的 android:textColorSecondary
属性内容。因为资源工具知道此处是一个属性,所以省去了attr (完整写法:?android:attr/textColorSecondary
)。