原文链接:http://developer.android.com/guide/topics/ui/themes.html
原文标题:Applying Styles and Themes
原文版本:Android 2.2 r1 - 05 Aug 2010 8:29
中文翻译:Jack Yu ([email protected])
仅供非盈利使用,转载请保留出处及译者信息
应用Style和Theme
style是用于指定View或window的外观、格式的一系列属性集合。style可以指定诸如高度、补白(padding)、字体颜色、字体大小、背景颜色等属性。style定义在一个不同于用来定义布局的XML资源中。
Android中的Style与网页设计中的层叠样式表有着相似的原理——它们允许你将设计和内容分离开来。
例如:通过使用一个style,你可以将下面这个布局XML:
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#00FF00"
android:typeface="monospace"
android:text="@string/hello" />
转换成这样:
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
所有这些与风格相关的属性被从布局XML中移走,放入一个叫做CodeFont的风格定义中,然后通过style属性应用。在下面的章节中你将看到此style的定义。
theme是一个应用于整个Activity或整个应用程序的style,而不是某一个单独的View(正如上面例子中那样)。当一个style被当作一个theme来应用时,此Activity或应用程序中的每个View都将会应用其所能支持的每个style属性。例如,你可以将CodeFont style作为theme应用在一个Activity上,那么此Activity中所有文本都将是绿色等宽字体。
定义Style
要创建一套style,请保存一个XML文件到你的工程的res/values/目录下。此XML文件的名称可以随意,但必须使用.xml作为扩展名,且必须保存在res/values/文件夹中。
此XML文件的根节点必须是<resources>。
对每个你要创建的style,添加一个<style>元素到XML文件中,其拥有一个name,用来唯一标识此style(name是必须的)。然后为此style中的每一个属性添加一个<item>元素,其有一个name和一个值。<item>的值可以是一个关键字字符串、一个十六进制颜色、一个到其它资源类型的引用,或者是其他值,决定于具体的style属性。这里有一个单独的style例子:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont" parent="@android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
每个<resources>元素的子节点在编译时都被转换为一个应用程序资源对象,其可以通过<style> 元素的 name属性的值来引用。此示例style可以通过@style/CodeFont来在一个布局XML中引用(正如先前介绍中所演示的)。
<style>中的parent属性是可选的,用来指定另外一个style的资源ID,前者继承后者的所有属性。你可以覆写继承来的style属性,如果你想那样做的话。
记住,你想用作一个Activity或一个应用程序theme的style,与应用在一个View上的style定义方式是相同的。一个如同上面那样定义的style可以应用作一个View的style,或者一个Activity或应用程序的theme。如何将一个style应用在一个View上,或者作为一个theme应用在一个应用程序中,我们稍后将作讨论。
继承
<style>元素中的parent属性使得你可以指定一个style,从其中继承属性。你可以通过这种途径来从一个现有的style中继承属性,然后只用定义你想改变或添加的属性。你可以从你自己创建的style或者平台内建的style中继承。(参见下面的使用平台Style和Theme,以获得关于继承Android平台预定义的style的信息)例如你可以继承Android平台的默认文本外观并修改它:
<style name="GreenText" parent="@android:style/TextAppearance">
<item name="android:textColor">#00FF00</item>
</style>
如果你想继承你自己定义的style,你不必使用parent属性,而是将你想通过继承创建的新style的name前加上要继承的style的name,中间用一个点分隔。例如,创建一个继承自前面定义的CodeFont的style,把颜色改为红色,你可以像这样编写新style:
<style name="CodeFont.Red">
<item name="android:textColor">#FF0000</item>
</style>
注意到在<style>标签中并没有parent属性。因为name属性以CodeFont起始(你已创建的一个style),此新style继承所有CodeFont的属性。此新属性覆写android:textColor属性将文本指定为红色。你可以通过@style/CodeFont.Red引用此新style。只要你愿意,你可以像这样继续继承很多次,只要更换句号前的名称即可。例如,你可以扩展CodeFont.Red使其字体变得更大:
<style name="CodeFont.Red.Big">
<item name="android:textSize">30sp</item>
</style>
它从CodeFont 和CodeFont.Red同时继承,然后添加android:textSize属性。
注意: 这种技巧仅适用于将你自己定义的资源链接起来。你不能用这种方式继承Android内建的style。要引用一个诸如TextAppearance的内建style,你必须使用parent 属性。
Style属性
到目前,你已明白了一个style是如何定义的,你需要学习由<item>元素定义的哪些属性是可用的。你很可能已经熟悉了某些,比如layout_width和textColor。当然,有更多的style属性供你使用。
寻找适用于某个特定View的属性的最佳去处是相对应的类参考,其列出了所有受支持的XML属性。例如,在表格TextView XML attributes中列出的所有属性可以被用在TextView元素(或其子类)的style定义中。其中有一个列出的属性是android:inputType,那么你通常可能将此android:inputType属性放置在一个<EditText>元素中,向下面这样:
<EditText
android:inputType="number"
... />
你也可以为包含此属性的EditText元素创建一个style:
<style name="Numbers">
<item name="android:inputType">number</item>
...
</style>
那么你的布局XML现在可以这样实现:
<EditText
style="@style/Numbers"
... />
这个简单的例子看起来增加了工作量,但当你添加越来越多的style属性并考虑到此style在不同地方的可重用性时,你会发现获益是巨大的。
关于所有可用的style属性,请参见R.attr。记住所有的View对象并不接受相同的style属性,所以你通常应该参考特定的View类,查看其所支持的style属性。然而,如果你对一个View应用了一个style,而其并不支持此style中某些属性,那么此View将应用那些它支持的,并简单忽略那些不支持的。
然而,一些style属性只能被当作一个theme来应用,而不受任何View元素的支持。例如那些用于隐藏应用程序标题、隐藏状态栏、或改变window的背景的style属性。这些style属性不属于任何View对象。想探究这些仅应用作theme的style属性,参见R.attr中那些以window开头的属性。举个例子,windowNoTitle和windowBackground是仅当style作为theme应用于一个Activity或应用程序时才有效的style属性。参见下一节以获得关于将一个style应用作一个theme的信息。
注意: 不要忘记对每个<item>元素中的属性冠以android: 命名空间前缀。例如:<item name="android:inputType">.
为UI应用Style和Theme
有两种方式设置一个style:
· 对一个独立的View,添加style属性到你的布局XML中的View元素中。
· 或者,对一个Activity或应用程序 添加android:theme 属性到Android manifest 的<activity>或<application>元素中。
当你应用一个style到布局中一个单独的View上,由此style定义的属性会仅应用于那个View。如果一个style应用到一个ViewGroup上,那么子View元素并不会继承应用此style属性——仅有你直接应用了style的元素才会应用其属性。然而,你可以通过将其作为theme来应用的方式应用一个style到所有View元素上。
为将一个style作为一个theme来应用,你必须在Android manifest中将其应用到一个Activity或应用程序。当你这样做,此Activity或应用程序中的每个View都将应用其所支持的属性。例如,如果你应用前面示例中的CodeFont style到一个Activity,那么支持此文本style属性的所有View元素都将应用它们。任何View所不支持的属性将被忽略。如果一个View仅支持某些属性,那么它就只应用那些属性。
为View应用一个style
下面是如何在布局XML中为View设置style的方法:
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
此时TextView将应用由名为CodeFont的style所定义的属性。(参见前面定义Styles中的示例。)
注意: style属性不使用android: 命名空间前缀。
为Activity或应用程序应用一个theme
为对你的应用程序中所有activity设置一个theme,请打开AndroidManifest.xml文件并编辑<application>标签,使之包含android:theme属性和style名称。例如:
<application android:theme="@style/CustomTheme">
If you want a theme applied to just one Activity in your application, then add the android:theme attribute to the <activity> tag instead.
如果你希望theme仅仅应用到你的应用程序中的某个Activity上,那么就将android:theme属性添加到<activity>标签中。
正像Android提供的其他内建资源一样,有许多你可以使用的预定义theme ,而不用自己编写它们。例如,你可以使用Dialog theme使你的Activity变得像一个对话框:
<activity android:theme="@android:style/Theme.Dialog">
或者你想让背景变成透明的,那就使用透明主题:
<activity android:theme="@android:style/Theme.Translucent">
如果你想使用一个theme,但也想调整它,那么你可以将其作为你的自定义theme的parent。例如,你可以修改传统的对话框theme来使用你自己的背景图像:
<style name="CustomDialogTheme" parent="@android:style/Theme.Dialog">
<item name="android:windowBackground">@drawable/custom_dialog_background</item>
</style>
然后在Android Manifest中使用CustomDialogTheme代替Theme.Dialog:
<activity android:theme="@style/CustomDialogTheme">
使用平台Style和Theme
Android平台提供了大量的style和theme供你在你的应用程序中使用。你可以在R.style类中找到所有可用的style。要使用这些style,用句号替换style名称中的下划线。例如,你可以通过"@android:style/Theme.NoTitleBar"应用Theme_NoTitleBar theme。
然而,R.style没有好的文档,没有透彻叙述这些style,所以查看这些style和theme的实际源代码将使你更好理解每个style属性提供了什么功能。为更好参考Android的style和theme,参见下列源代码: