Android开发指南 - 样式和主题
样式和主题(Styles and Themes)
一个样式(Style)是一个包含了指定样子和格式的作用于视图控件(View)或者窗体(Window)属性集合。一个style可以指定很多属性,比如高度,填充,字体颜色,字体尺寸,背景色等。一个Style在xml资源文件中定义,并且和在xml中指定的布局区分开来。
在Android里的样式和Web设计中的CSS共享一个相似的原理,它们允许你分离设计(Design)和内容(Content).
举个例子,通过使用一个style,你可以让你的布局xml像下面这样:
android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#00FF00" android:typeface="monospace" android:text="@string/hello" /> 并且,可以变成下面这样: style="@style/CodeFont" android:text="@string/hello" /> 所有关联到style的属性已经在布局xml中被删除了,并且放在一个叫做“CodeFont”style中定义了。它通过一个style属性被应用上。在下面的章节,你将会看到如何定义style。 一个主题(Theme)也是一个style,它被应用在所有的Activity或者application上,而不是个别的视图控件(View)(像上面的示例一样)。当一个style被当做一个theme来应用,每一个activity或者application中的视图控件将应用每一个它支持的样式属性。比 如,你可以在activity上使用相同的CodeFont样式作为一个theme,这时Activity里的所有内部字体将会变成CodeFont样式的字体样式变成绿色的等宽字体。 定义一个样式Style 为了创建一些样式,你可以保存在你的工程下的 res/Values/ 文件夹下的一个XML文件中。XML文件的名字是随意的,但是必须扩展名是 .xml 并且存放在 res/Values/ 文件夹下。 XML文件的根节点必须是 为你创建的每个样式,添加一个 每一个 如果你想要继承你自己创建的样式,你不需要一定适用parent属性。作为替代,可以为一个你想继承的样式的名字构建前缀而作为你的新的样式的名称,中间用“点”隔开。比如,为了创建一个样式,比如继承自上面的CodeFont样式,但是让颜色变成红色,你可以这样写你的新样式: 注意 这里从CodeFont和CodeFont.Red继承了,又添加了android:textSize 属性 注意:这样的通过链接名称的方式来继承的方法,仅仅能用于你自己定义的资源文件中的样式。你不能用于继承安卓内置的样式。要想引用内置的样式,比如TextAppearance,,你必须使用parent属性。 样式属性 现在,你明白了如何定义一个样式,你需要去学会在 寻找可以应用在指定视图控件上的属性的最好的地方是相应的类引用,它列出了所有支持的XML属性。比如所有在表格TextView XML attributes 中列出的属性,都可以应用在一个样式的定义中作用在TextView元素上(或者它的子类)。在引用中被列出的一个属性叫做android:inputType的,这样你可以再 android:inputType="number" ... /> 你可以为EditText 元素创建一个样式,包含这个属性,来代替上面: ... 这样你的布局用的XML能够这样实现样式: style="@style/Numbers" ... /> 这个简单的示例看起来多做了一些工作,不过当你添加更多的样式属性并且把在多处可重用样式的能力作为参考因素的话,你的付出将是值得的。 获得所有可用样式的属性的引用(reference),请参阅R.attr 引用。记住,所有的视图控件对象不接受所有相同的属性,这样你可以平常的引用图为视图控件类指定支持的样式属性。然而,如果你为某个视图控件应用了一个样式,这个样式包含的属性中不是都被支持的,视图控件将会应用那些属性中的可被支持的并且简单的忽略其他的。 一些样式属性,不被支持在视图控件里使用,仅仅能作为主题使用。那些样式属性应用在所有的窗体上,不能用在任何视图控件上。比如有些样式属性可以隐藏应用程序的标题,隐藏状态条,或者更改窗体的背景。那些类型的样式属性不属于任何视图控件对象。要发现更多仅仅作用于theme主题的属性,查看R.attr 引用中的以windows开始的属性。比如,windowNoTitle 和windowBackground 属性只能在应用于activity和application 时发生作用。参阅下一章节可以获得更多“在theme中应用样式”的内容。 注意:在 在UI上应用样式和主题 有两种方式设置一个样式: 为单个视图控件指定样式,在XML布局文件中的视图元素上添加style属性。 为整个activity或者application指定样式,在manifest.xml中的 当你为布局里的单个控件中应用一个样式,你的样式中定义的属性都会应用在这个视图组件中。如果你的样式应用在一个ViewGroup中,它的所有子控件元素将不能继承这些样式的属性,只有你直接指定的那个视图元素可以应用这些属性。不过,你仍然可以通过主题的方式为你的应用下的所有视图元素应用样式。 要想应用一个主题,你必须在manifest.xml中为activity或者aplication上应用样式。当你这么做,每一个Activity或者aplication里的视图元素都将应用这些样式中它支持的属性。比如,如果应用上面提到的CodeFont样式在一个Activity上,这是所有的支持文本样式属性的视图元素将应用它们。一些不支持这些属性的视图元素将忽略它们。如果一个视图支持一部分属性,那么它将只应用这些属性。 在视图元素中应用样式 下面演示如何在XML布局中设置一个样式: style="@style/CodeFont" android:text="@string/hello" /> 现在 TextView将具有样式,像CodeFont定义的属性描述的一样。你可以参考上面的示例。 注意:样式style 不需要使用androidoi: 命名空间前缀。 在activity或者application中应用样式 要想再你的所有activity或者application上使用样式,打 开AndroidManifest.xml 并且修改 含android:theme 属性并指定一个样式名称,比如: 如果你想为你的应用中的某个activity使用样式,那么添加android:theme 到你的 安卓提供了一些内置资源,你可以使用这些预先定义好的样式,而不用自己再重新写了。 比如,你可以使用Dialog主题让你的Activity 表现的像一个对话框: 或者你想让你的背景透明,使用透明主题: 如果你喜欢主题,但是想开足马力使用它,那么你可以添加它到你的自定义主题中的parent属性上继承它。比如,你可以修改传统的 light theme 主题并使用你的自己的颜色,像下面这样: 注意上面用到的颜色在其他资源中被提供,这里,因为android:windowBackground 属性仅仅支持其他资源的引用,不像android:colorBackground属性可以指定一个颜色描述文本。 现在,在你的Mnaifest文件中,可以使用CustomTheme 代替 Theme.Light: 选择一个平台支持的样式作为基础 安卓较新的版本为应用提供了额外的可用的样式,同时你可能想要使用它们在那些平台上运行,并且仍然和老版本保持兼容。你可以通过自定样式做到,使用“资源选择器"来切换不同的父主题,基于平台版本。 比如,下面是一个自定义样式的声明,这个样式是个简单的标准平台默认的 light theme主题。它可能被放置在res/valeus文件夹下的 XML文件中(经典的是在 res/values/styles.xml)。 ... 当应用跑在Android 3.0(API级别11)或者更高以上时,可以让这个样式使用较为新一些的holo风格主题,你可以放置一个可供选择的声明样式防止在res/values-v11这个文件夹下的XML文件中,但是让这个样式继承自 holo风格的主题: ... 现在可以像任意其他那样来使用这个主题,并且当跑在安卓3.0以上时,你的应用程序会自动切换到holo风格的主题。 在R.styleable.Theme. 里,可以找到一个标准的属性列表供你使用。 关于更多的信息,像比如主题和布局,基于平台版本或者设备配置等切换资源文件选择,你可以阅读Providing Resources 。 使用平台样式和主题 安卓平台提供了很多样式和主题,供你在应用程序中使用。在R.style 类里你可以找到可以用的引用。为了使用这里列出的样式,你可以使用”点“替换所有的下划线分割的样式名称,比如,你可以通过”"@android:style/Theme.NoTitleBar".来使 用Theme_NoTitleBar 样式。 R.style 引用,然而,不是和好的文件记录,并且不能全面的描述样式,那么查看那些样式和主题的实际的资源代码可以给你更好一些关于”各个被提供样式属性“的的理解。获得更多关于样式和主题的引用,你可以看下面的源代码: Android Styles (styles.xml) Android Themes (themes.xml) 那些文件将通过实例帮助你学习。比如,在安卓的主题源代码中,你将找到一个声明