11.2 风格(Style)资源与主题(Theme)
源代码目录:src/ch10/Style
风格资源使用<style>标签定义,需要在res/values目录中的任意XML格式的文件中设置,主要功能是成批设置属性。例如,如果有10个TextView控件都需要设置android:textColor和android:textSize属性,而且属性值完全相同,就可以将设置这两个属性的代码放到风格资源中,然后在<TextView>标签中使用style属性(不能加android命名空间)指定该风格资源即可。
风格资源除了可以设置系统内置的属性(android:textColor、android:textSize等)外,还可以设置自定义属性,甚至可以限制属性值的类型。
在前面章节使用的布局文件中经常会遇到“@”,通过这个符号可以引用各种资源,而要引用风格资源中的具体属性,就需要使用“?”,格式如下:
?[<package_name>:][<resource_type>/]<resource_name>
下面的例子是两个自定义的风格资源,并且限制了mycolor属性只能接受颜色值。
源代码文件:src/ch11/Style/res/values/style.xml
<resources>
<!-- 所有自定义的属性(如mycolor)必须通过attr标签定义,而且要指定属性值类型
如本例中的color -->
<declare-styleable name="CustomText">
<attr format="color" name="mycolor" />
</declare-styleable>
<!-- 第1个自定义风格资源 -->
<style name="CustomText">
<!-- 设置android:textSize属性的值为40sp -->
<item name="android:textSize">40sp</item>
<!-- 设置android:textColor属性的值为#F00 -->
<item name="android:textColor">#F00</item>
<item name="android:src">@drawable/ic_launcher</item>
</style>
<!-- 第2个自定义风格资源,该风格资源继承自系统的Theme风格资源 -->
<style name="MyTheme" parent="@android:style/Theme">
<item name="android:colorForeground">#00F</item>
<!-- 设置了自定义属性(mycolor)的值 -->
<item name="mycolor">#FF0</item>
</style>
</resources>
风格资源可以用于如下两种标签。
<application>或<activity>标签。这两个标签都有一个android:theme属性,该属性可以直接指定风格资源。如果<application>标签的android:theme属性指定了一个风格资源,就意味着整个应用程序都使用了该风格资源。如果<activity>标签的android:theme属性指定了一个风格资源,就意味着只有<activity>指定的窗口使用该风格资源。通过android:theme属性设置的风格资源也称为主题资源。但读者要清楚,风格资源和主题资源实际上是一种资源。
任何的视图标签,例如<TextView>、<ImageView>、<Button>等。在这些标签中使用style属性设置风格资源。
现在首先将MyTheme应用于当前的窗口,代码如下:
源代码文件:src/ch11/Style/AndroidManifest.xml
<activity
android:label="@string/app_name"
android:name=".Main" android:theme="@style/MyTheme">
……
</activity>
Main窗口中的所有控件都可以使用MyTheme资源中的属性。接下来在布局文件中将CustomText资源应用于<TextView>、<Button>和<ImageView>标签,代码如下:
源代码文件:src/ch11/Style/res/layout/main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
style="@style/CustomText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="类型资源" />
<Button
style="@style/CustomText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="按钮" />
<!-- android:textColor属性使用了MyTheme资源中设置的android:colorForeground属性值 -->
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:textColor="?android:colorForeground"
android:textSize="20sp" />
<!-- android:textColor属性使用了MyTheme资源中设置的mycolor属性值 -->
<ImageView
style="@style/CustomText"
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:background="?mycolor"/>
</LinearLayout>
现在运行程序,会看到如图11-12所示的效果。
▲图11-12 风格资源
使用风格资源应了解如下几点。
风格资源使用<style>标签定义,每一个属性的值使用一个<item>标签设置。
风格资源既可以设置系统属性(带“android:”的属性),也可以设置自定义属性。
如果设置自定义属性,这些属性必须事先使用<declare-styleable>标签定义,每一个自定义属性用一个<attr>标签指定,并且需要使用format属性设置属性值的类型,例如,color表示属性值必须是颜色值,boolean表示属性值必须是布尔类型,enum表示属性值必须是枚举类型。
任何的视图标签都可以使用“?”引用当前窗口或应用程序使用的主题(风格资源)中的属性值。
风格资源中的属性可以任意设置。如果当前应用该风格资源的<application>、<activity>、<TextView>、<ImageView>等标签没有风格资源中的某些属性,这些属性会被忽略。例如,CustomText风格资源中设置了android:src属性,但<TextView>和<Button>标签并没有android:src属性,所以在这两个标签中该属性将被忽略。由于<ImageView>标签有android:src属性,所以在<ImageView>标签应用CustomText风格资源时android:src属性被设置。
风格资源可以被继承,可以使用<style>标签的parent属性指定父风格资源。例如,MyTheme继承了系统风格资源Theme,所以parent属性值为“@android:style/Theme”。
扩展学习:系统风格资源
在很多Android应用中经常会看到窗口和控件使用很多系统的风格资源,那么我们怎么知道当前Android系统有哪些系统风格资源呢?
要查找Android系统支持的风格资源,需要Android SDK。在Android SDK中将应用于控件和窗口的风格资源分开存储。应用于控件的风格资源被存储在styles.xml和styles_device_defaults.xml文件中。应用于窗口的风格资源被存储在themes.xml和themes_device_defaults.xml文件中,读者可以在如下目录找到这4个文件。
<Android SDK根目录>/platforms/android-17/data/res/values
打开styles.xml和styles_device_defaults.xml文件,会看到很多预定义的风格资源。例如,用于设置按钮栏样式的ButtonBar资源。
<style name="ButtonBar">
<item name="android:paddingTop">5dip</item>
<item name="android:paddingStart">4dip</item>
<item name="android:paddingEnd">4dip</item>
<item name="android:paddingBottom">1dip</item>
<item name="android:background">@android:drawable/bottom_bar</item>
</style>
如果将ButtonBar资源应用于控件,可以使用下面代码设置。
style="@android:style/ButtonBar"
打开themes.xml和themes_device_defaults.xml文件也会看到很多风格资源,这些资源通常会被用于窗口。例如经常使用的对话框风格资源就有很多,在themes.xml文件中有Theme.Dialog,在themes_device_defaults.xml文件中有Theme.DeviceDefault.Dialog。这两个对话框的风格略有差异,可以直接使用下面的代码为窗口设置系统风格资源。
android:theme="@android:style/Theme.DeviceDefault.Dialog"
由于系统限制,在这4个资源文件中有一些风格资源在第三方应用程序中无法使用,要想知道哪些资源能用,可以使用ADT的Content Assist。在android:theme或style属性中输入“@android:style/”,然后按Content Assist快捷键(通常为Alt+/),就会显示可用的系统风格资源列表,如图11-13所示。
▲图11-13 可用的系统风格资源列表