Android 为我们提供了一系列的控件,TextView、Button、ImageView 等等,但是讲真,这些组件呆板单调,很多情况下,需要我们对其进行美化。
我们可以使用 style、theme 以及一系列 Drawable 来美化我们的窗口和组件。
style 可以帮助我们设置 View 的高度、填充、字体颜色、字体大小、背景色等等许多属性。style 在 XML 文件中设置,和设置布局的 XML 是分开的。
例如你可以把下面这个布局 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" />
所有和 style 相关的属性都从布局文件中移动到了一个名为 CodeFont 的 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>
style 的定义和使用大致如此,但是其可以实现的功能却丰富的多。
每个 style 都是一个 XML 文件,保存在 /res/values/
当中,可任意指定该 XML 文件的名称,但它必须使用 .xml
扩展名,并且必须保存在 res/values/
文件夹内。
style 文件必须以 <resources>
为根节点。
每创建一个 style,需要向根节点中添加一个 <style>
元素,该元素必须有唯一的 name
属性作为唯一标识以供组件引用。每个 style 的属性都必须添加在一个 <item>
元素当中,该元素带有声明样式属性以及属性值的 name
(该属性为必需属性)根据样式属性,
<?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">#FF0000</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
我们可以通过 <style>
元素中的 parent
属性为该元素设置父元素,它可以继承或复写父元素的所有 item。
style 可以多重继承,用 .
来进行多重继承,例如:
<style name="CodeFont.Red.Big">
<item name="android:textSize">30sp</item>
</style>
这个样式就是分别继承了 CondeFont
和 CondeFont.Red
,然后又添加了 textSize 属性(但是似乎是脱裤子放屁,但官方文档就是这么写的)。
我们都可以在 style 中设置哪些属性呢?答案是:我们的 View 支持哪些属性,我们就可以设置哪些属性(这不是废话么...),我们可以通过查看控件代码来查找适用的属性,所有的可用 style,可以查看 R.attr 参考资料。
不过,某些样式属性任何 View 元素都不提供支持,只能以主题形式应用。 这些样式属性应用于整个窗口而非任何类型的 View。例如,主题的样式属性可以隐藏应用标题、隐藏状态栏或更改窗口的背景。 这些类型的样式属性不属于任何 View 对象。要发现这些仅主题样式属性,请在 R.attr 参考资料中查看有关以 window 开头的属性的内容。 例如,windowNoTitle 和 windowBackground 是只有在样式以主题形式应用于 Activity 或应用时才起作用的样式属性。
注:别忘了使用
android:
命名空间为每个<item>
元素中的属性名称添加前缀。 例如:<item name="android:inputType">
。
应用样式主要有两种方法:
<activity>
或 <application>
元素添加 android:theme
属性。需要注意的是,当我们给一个 View 来设置 style 的时候,该 View 会应用这个 style,当我们给一个 ViewGroup 来设置 style 的时候,效果只产生于该 ViewGroup 本身,其子 View 并不会产生影响,不过我们可以通过设置 theme 来将样式作用于所有 View。
我们设置一个 style 给一个 View 或者 ViewGroup,目标只会对本身属性支持的 style 内容进行应用,不支持的属性将会忽略。
举个例子:
<style name="CodeFont">
<item name="android:typeface">monospace</item>
<item name="android:textSize">20dp</item>
</style>
这个 style 文件只是修改文本字体,当我们在清单文件中 <activity>
元素中通过 android:theme
来设置全局主题时,那么该 Activity 下所有字体都将变为 monospace 和 20dp,而不支持 typeface 和 textSize 属性的组件将自动忽略该 style。
但是如果将该 style 设置给布局文件,那么布局文件下的 TextView 却并不会受到影响。
假如我们为一个 View 指定了某项属性,但是在 XML 中又重新指定了该属性,那么该属性将以 XML 中重新设定的为准。
除了对 View 做一些美化工作之外,我们还可以对我们的 Activity 进行一些特殊化设置,有两种方法:
<application>
当中添加 android:theme
属性,应用所有 Activity 全部生效<activity>
当中添加 android:theme
属性,只有当前 Activity 生效正如 Android 提供了其他内建资源一样,有许多预定义主题可供您使用,可免于自行编写。 例如,您可以使用 Dialog 主题,为您的 Activity 赋予类似对话框的外观:
<activity android:theme="@android:style/Theme.Dialog">
或者,如果您希望背景是透明的,则可使用 Translucent 主题:
<activity android:theme="@android:style/Theme.Translucent">
如果您喜欢某个主题,但想做些调整,只需将该主题添加为您的自定义主题的 parent。 例如,您可以像下面这样对传统明亮主题进行修改,使用您自己的颜色:
<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,无法为其提供颜色字面量。)
现在,在 Android 清单内使用 CustomTheme 替代 Theme.Light:
<activity android:theme="@style/CustomTheme">
新版本的 Android 可为应用提供更多主题,您可能希望在这些平台上运行时可以使用这些新增主题,同时仍可兼容旧版本。 您可以通过自定义主题来实现这一目的,该主题根据平台版本利用资源选择在不同父主题之间切换。
例如,以下这个声明所对应的自定义主题就是标准的平台默认明亮主题。 它位于 res/values
之下的一个 XML 文件(通常是 res/values/styles.xml
)中:
<style name="LightThemeSelector" parent="android:Theme.Light">
...
</style>
为了让该主题在应用运行在 Android 3.0(API 级别 11)或更高版本系统上时使用更新的全息主题,您可以在 res/values-v11
下的 XML 文件中加入一个替代主题声明,但将父主题设置为全息主题:
<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
...
</style>
现在像您使用任何其他主题那样使用该主题,您的应用将在其运行于 Android 3.0 或更高版本的系统上时自动切换到全息主题。
R.styleable.Theme 提供了可在主题中使用的标准属性的列表。
如需查看更详实的 Android 样式和主题参考资料,请参阅以下源代码:
Android 中的资源体系庞大而复杂,因为篇幅问题,可以看官方的链接,已经讲解的很清楚了: