Android开发权威指南(第二版)
上QQ阅读APP看书,第一时间看更新

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 可用的系统风格资源列表