Android的Style和Theme 译文

Style 是Window和View的一种外观和格式的属性集合。它可以作为高度,间距,字体大小,背景颜色等属性。Style是一种 xml 资源文件,放在和布局文件不同的文件夹里;

Style 的设计理念和 Web一脉相承——即它们都允许你把内容和样式分离。

例如,你用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" />
你看上面的例子,全部的样式属性都从布局文件里放到一个名为CodeFont的Style里,它是就是一个Style属性。你在接下来的内容里看到这个布局是怎么被定义的。

你可以把Theme当成是整个Activity或者整个程序的样式(Style),它的覆盖范围比上面例子里那个view的范围更大。当一个Style被用作一个Theme时,整个Activity或者整个程序里的每一个View将会用到同样style属性,如果那些属性它们支持的话。举个例子,你可以在一个Activity的样式设置成上面CodeFont,这样的话Activity里面的所有字体都会成绿色的“monospace”。

定义Style


在你项目里的res/values/路径下生成一个xml文件,然后在里面创建出一组style。这个XML文件名你可以任意的取,只要它必须以.xml为后缀并保存在res/values/路径下就行。

XML文件必须以<resources>为根节点。

你每要创建一个style就在xml里增加一个带唯一名称(name)<style>元素(name是必须的)。然后在style里增加一个带有name和value的<item>属性(name和value也是必须的)。<item>里的value值可以是一个字符串,一个十六进制的颜色值,一个资源引用,或者其他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>的命名生成值引用。这个例子里的style可以被布局文件用@style/CodeFont引用。(像文章开头那样)

在<style>里还有一个parent属性,这个元素是可选的,你可以在这个属性里指定另一个资源ID来作为你想要继承的style。然后你可以复写继承而来的属性。
请注意,把style作为Activity或整个程序的主题也是像把style作为一个View的样式那样在xml文件里那样定义。像上面例子里的style可以应用在单个视图View里或者作为Activity或整个程序的主题。至于怎样把一个style应用到单个View里或作为一个程序的主题,稍候会提到。

继承


在<style>元素里,parent这个属性可以让你定义一个style去继承其他已存在的style,然后只增加或者复写那些你需要的属性。已存在的style包括你自己创建的和系统本身带有的(系用自带的style和theme,这个链接有Android平台自带的style和theme)。例如,你可以继承Android平台下面默认的text appenrence 样式然后修改它:
 <style name="GreenText" parent="@android:style/TextAppearance">
        <item name="android:textColor">#00FF00</item>
 </style>
如果你想要继承那些你自己定义的style,你不一定需要用parent这个属性。你可以用另一种方式代替,把你想要继承的那个style作为前缀,用一点把你想要新建的style分隔开来。例如,创建一个继承自上面例子里CodeFont style,只是把颜色设置红的,你可以像下面这样创建一个新的style:
<style name="CodeFont.Red">
        <item name="android:textColor">#FF0000</item>
</style>
你看上面的例子里,在style里并没有parent属性,只是在name属性里把CodeFont作为前缀放在Red的前面,这样也能继承CodeFont里面的所有属性。这个style复写了textColor属性,将字体颜色变成红的。这样定义以后,你就可以用@style/CodeFont.Red 这种方式来引用这个新的style了.
你还可以像这样的格式继续继承无数次,例如,你可以扩展CodeFont,像下面这样:
    <style name="CodeFont.Red.Big">
        <item name="android:textSize">30sp</item>
    </style>
像上面这种写法的style就是继承自CodeFont 和 CodeFont.Red,然后加上android:textSize 属性。

请注意:这种继承写法,只能运用在你自己定义的style样式,你可不能把它运用到Android平台自带的style样式上。对于像TextAppearance这种Android平台自带的样式,你只能乖乖的用用parent属性来继承。 

样式属性


现在你知道了怎么定义一个style了,接下来你需要知道在<item>这个元素里有哪些style属性是可以用的。你可能对于一些属性很熟悉了,例如layout_width和textColor。当然,还有好多属性你可以用。

找到这些属性最好的地方是View的相应类的参考,那里列出xml里支持的所有属性。例如,所有TextView可以用在style里的属性都罗列在TextView XML attributes这张表里。还有一些是列有某种属性值的表,例如这张android:inputType,你可以将里面的属性值作为<EditText>的一个属性,像下面的例子:
<EditText
    android:inputType="number"
    ... />
你也可以创建一个style作为EditText的属性替代上面那种方式:
<style name="Numbers">
  <item name="android:inputType">number</item>
  ...
</style>
这样你的EditText布局文件就可以用用到这个style啦:
<EditText
    style="@style/Numbers"
    ... />
这个简单的例子可能会让你觉得用了style反而更麻烦了,其实未必,当你在一个真实的项目里,把很多需要复用到的属性写到一个style里,让所有用到的那些属性的地方使用,那时你就会觉得节省里很多麻烦。

对于所有style 可用属性的引用,你可以看看R.attr这个链接。注意一下,并不是所有的View类都能接受全部同样的style属性,所以你最好能尽可能的在style里创建那些需要应用此style所接受的属性。然而,如果一个View视图应用了一个style,但是这个View并不支持style里的所有属性,那么这个View将使用那些它用得到的属性,并忽略它那些用不到的属性。

还有一些style属性,只支持被应用到主题theme里,而不支持用到单个View里。这些style属性只支持运用到整个窗口而不支持单个View。例如,一些style属性作为作为主题可以隐藏掉程序的标题、状态栏,或者改变整个窗口的背景色。这些属性并不属于任何一个视图View类。如果你想要知道有哪些style属性属于窗口特有的,你可以参考R.attr这个链接里面开头里的内容。例如,windowNoTitle和windowBackground这两个属性只在当style应用到Activity或者整个程序里才有用。下一节内容就是关于style是怎么作为主题应用到Activity或程序里的。

注意:不要忘了在每个<item>元素里,都需要把android:这个命名空间放在前面,例如:<item name="android:inputType">。

在UI上设置Style和Theme


有两种方式设置style:
1 : 对于单独的视图View,style在View的布局文件里设置属性就行。
2 : 对于整个Activity或整个程序来说,只要在AndroidManfest里的把android:theme属性加到<activity>标签或<application>里就行。

当你只在单个View里设置style属性时,style里面的属性值只对这个view起作用。如果你在ViewGroup设置一个style,是不会对ViewGroup里面的子视图起任何作用的,它只作用于所设置的视图。如果你想设置一个style让布局文件下面的子视图都起作用,可以把style作为theme来设置。

想要把style当作theme,你必须在AndroidMainfest里的Activity或appliaction里设置。你这么作的话,style里的属性会在Activity或整个程序下面的每一个视图起作用,如果那些属性它支持的话。例如,如果你把前面例子里的CodeFont style设置在一个Activity里,那么text style里的属性会在它下面的所有视图View里生效。对于那些它不支持的属性它会自动忽略掉,View只作用那些它能够支持的属性。

在View里面设置style


下面是在View布局里设置一个style:
<TextView
    style="@style/CodeFont"
    android:text="@string/hello" />
现在style CodeFont里的属性将被设置进TextView里。注意:设置style属性时不用加上android: 这个命名空间。

在Activity或application里设置主题


如果想要为让一个程序里的所有activity拥有同个主题,你可以打开AndroidMainfest.xml文件,在<application>标签里加上android:theme属性和所要引用style的名字。例如:
<application android:theme="@style/CustomTheme">
如果你想要设置一个activity的主题,只要把android:theme属性加到<activity>标签里就好。
其实,Android自身也提供了很多资源文件供你调用,避免所有属性都让你亲自创建。例如,你可以用Dialog主题来让你的Activity看起来像个对话框:
<activity android:theme="@android:style/Theme.Dialog">
又或你想让它的背景变得半透明,你只要用Translucent这个主题就行:
<activity android:theme="@android:style/Theme.Translucent">
如果你喜欢一个主题,但你想调整一些属性,你可以新建一个主题然后用parent属性去继承它。例如,你可以加上自己的颜色在普通的 light 主题上面:
<color name="custom_theme_color">#b0b0ff</color>
<style name="CustomTheme" parent="android:Theme.Light">
    <item name="android:windowBackground">@color/custom_theme_color</item>
    <item name="android:colorBackground">@color/custom_theme_color</item>
</style>
(请注意,上面例子里的android:windowBackground属性值只支持已经定义好了的颜色引用,不像android:colorBackground属性值还可以直接用颜色的数值)
现在可以在AndroidMainfest里用你自定义的主题取替代Theme.Light了:
<activity android:theme="@style/CustomTheme">

选择一个基于平台版本的主题


对于新版本的Android,会增加一些额外的主题,你可能会想让这些主题运用于那些老版本的程序上。你可以在不同版本的资源文件目录下,自定义一个主题去继承新旧版本的主题。

例如,下面的例子就声明了一个自定义的主题,在一个较老的系统平台上,它的目录是在 res/values下(通常是 res/values/styles.xml):
<style name="LightThemeSelector" parent="android:Theme.Light">
    ...
</style>
在新版本Android 3.0(API11)以上,使用上面这个主题就得继承自 新主题 holographic 了, 你可以在其他的资源目录下面去声明这个主题,只要它的parent属性是holographic系的 :
<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
    ...
</style>
现在你可以使用任何主题像这个例子一样,你的程序将自动转换到holographic 系列主题,只要你的程序运行在Android 3.0 或以上。

关于标准主题里有哪些可以用到的属性你可以在R.styleable.Theme里面查找。

如果你想知道不同版本的资源,像主题和布局这些,在不同平台和设备里有哪些差异,你可以看看Providing Resource这个文档。

使用平台的style和theme


Android平台提供里一个"d98"的集合styles和主题(原文:a d98 large collection of styles and themes),你可以在你的程序里使用。你可以在R.style类里找到所有你能够引用的styles。在使用链接里的style时,你需要把下划线去掉。例如,你可以用“@android:style/Theme.NoTitleBar”这种方式来使用Theme_NoTitleBar主题。

然而,上面那篇R.style的文档,并不是一份好文档,它没有详尽的描述style,所以你是最好看看这些样式和主题的源码,它会让你有更好的认识。对于Android的样式和主题有两份源码文档可供参考:


这两份文档通过例子可以很好的帮助到你。例如,在Android 主题的源码里,你将会找到<style name="Theme.Dialog">的声明,在声明里,你将看到Android框架关于dialog样式都定义了哪些属性。

如果你想知道更多关于styles 和 themes在xml里的语法,请看Style Resource这份文档。

关于style 或 theme里有哪些属性可以定义的更多信息(例如,"windowBackground" 或 "textAppearance"),请看R.attr或者相应View类文档。
 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。