Android 的样式和主题

概述:

Style(样式)是一系列指定View或者window长相和格式的属性. Style可以指定的属性比如高度(height),填充(padding), 字体颜色(font color), 字体大小(font size), 背景色等. 一种style可以定义在XML资源文件中. 这东西的设计理念就是将UI设计和内容设计分离. 比如通过style我们可以将这个layout文件:

<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有关的属性都被从layout文件中移除, 并存入一个名为CodeFont的style定义文件中.

主题(Theme)则是应用于整个Activity或者APP的样式, 而不是单个View. 当style在APP内部形成了统一的风格, 那么就成了一个主题. 比如我们可以将CodeFont作为一个主题设置给一个Activity, 这样所有的TextView就有了一样的样式.

定义style:

想要定义一组style, 我们需要在res/values/目录下创建XML文件. 文件名字没有限制, 但是后缀名必须为.xml. 该文件的根标签为<resources>. 对于我们想创建的每个style, 必须为其指定<style>标签并带有一个唯一的标识, 该标识使用name指定. 然后为style的每个属性增加<item>标签, 同样需要指定name作为style的属性, 然后为<item>指定该name的值, 该值可以是一个关键字的字符串, 一个十六进制的颜色, 一个到其它资源文件的关联信息, 或者其它可以接受的值, 这里是一个栗子, 它包含一个单独的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>标签的每个子标签都会在编译的时候被转化为一个APP资源对象,可以通过style的name属性的值来关联. 上面这段代码中的style可以在一个XML layout文件中使用@style/CodeFont关联它.

而<style>中的parent属性是一个可选的属性, 它指定了要继承的样式的资源ID, 如果需要的话我们可以重写继承的样式属性.

而theme的写法跟style是一样一样的. 像上面这样的style文件可以作为style应用于某个View, 也可以作为theme作用于某个Activity或者整个APP.

继承性:

<style>中的parent属性为我们指定了一个可以继承其属性的style. 我们可以使用该属性来继承一个现成的style, 然后修改或者增加我们需要改变的属性. 我们可以继承我们自己的style, 也可以继承平台提供的已有的style. 比如这里是一个继承平台style的栗子, 我们可以修改它的默认textColor:

    <style name="GreenText" parent="@android:style/TextAppearance">
        <item name="android:textColor">#00FF00</item>
    </style>

如果我们想要继承的style是我们自己写的, 那么我们不一定非要使用parent属性, 而是只需要使用想要继承的style的名字作为前缀并用圆点来分隔我们新的style的名字即可. 比如我们想要创建一个继承自CodeFont的新的style, 但是修改textColor为红色, 那么我们可以这样写:

    <style name="CodeFont.Red">
        <item name="android:textColor">#FF0000</item>
    </style>

这里并不需要一定指定parent属性, 但是因为name属性是以CodeFont开头的(前提是该style已经被我们创建了), 所以新的style继承了CodeFont的所有的属性. 然后新的style重写了android:textColor属性使字体颜色变为红色, 我们可以通过@style/CodeFont.Red来使用这个新的style.

我们还可以对CodeFont继续继承, 还可以扩展它的样式, 比如:

    <style name="CodeFont.Red.Big">
        <item name="android:textSize">30sp</item>
    </style>

新的样式继承了CodeFont和CodeFont.Red的属性, 然后还增加了自己的android:textSize属性.

这种模式只能用于继承我们自己的style. 我们不能使用这种方法来继承Android的自带style. 想要继承Android自带的style必须使用parent属性.

Style属性:

现在已经了解<style>, 那么该了解一下style的属性了, 也就是<item>. 我们应该对一些常用的已经很熟悉了, 比如layout_width和textColor. 当然还有很多我们可以使用的属性. 最好的了解每种View可以使用的属性的地方是它们的class reference, 那里有它们所有的可以支持的XML属性. 比如TextView(以及其子类)的可以使用的全部style定义在TextViewXML attribute中. 这里面包含一个android:inputType属性, 所以我们可以在<EditText>中使用androi:inputType像这样:

<EditText
    android:inputType="number"
    ... />

这样我们就可以为EditText创建一个带有该属性的style:

<style name="Numbers">
  <item name="android:inputType">number</item>
  ...
</style>

所以我们的XML可以通过指定style写成这样:

<EditText
    style="@style/Numbers"
    ... />

这个栗子很简单, 使用style好像还做了更多的事情, 但是如果我们的代码和控件都很多的时候, 使用style可以帮我们节省很多时间.

对于那些可以应用于所有的属性的style可以参考R.attr.但是我们应该记得不是所有的View对象都可以接受所有相同的style的, 所以通常我们应该为指定的View类提供指定的可以支持的style. 如果我们一意孤行的为一个View指定了它不能支持的style属性, 其实也没啥事, 它们会选择自己支持的生效, 不支持的就忽略了.

有些style属性则不能支持任何View而只能应用于theme, 这些style属性应用于整个window而不是应用于任何View. 比如, 有的style属性可以隐藏application title, 隐藏status bar, 或者改变窗口背景. 这些类型的style属性不属于任何View对象. 这些只能应用于theme的style属性可以到R.attr中的以window开头的属性中查看. 比如windowNoTitle和windowBackground就是只能作为theme应用于一个Activity或者APP的style属性.

另外切勿忘记<item>标签中的name属性需要用android:作为前缀, 比如<item name=”android:inputType”>.

将style和theme应用于UI:

有两种方式可以设置一个style:

第一种是对一个独立的View, 通过在XML文件中对View标签增加style属性.

第二种是针对整个Activity或者APP, 通过在manifest文件中对<activity>或者<application>增加android:theme属性.

当我们对一个独立的View使用style的时候, style中的属性只是应用于该View自己. 如果style是应用于一个ViewGroup, 那么它的子View却不会继承这个style, 只有直接应用的标签才会使用style, 然而我们可以通过将style作为theme应用于全部的View.

想要将style作为一个theme使用, 我们必须在manifest文件中将style应用于一个Activity或者application. 当我们这样做的时候, 在Activity或者application中的每个View都会使用style中它们可以支持的属性. 比如如果我们将CodeFont应用于一个Activity, 那么所有支持text style属性的View标签都将使用这个style. 不支持的则会忽略它.

将style应用于一个View:

我们可以这样将style应用于一个View:

<TextView
    style="@style/CodeFont"
    android:text="@string/hello" />

这样这个TextView就会使用这个名为CodeFont的style了. 注意style属性不使用android:作为前缀.

将style应用于一个Activity或者application:

想要为application中的所有Activity设置一个theme, 我们需要在AndroidManifest.xml文件中编辑<application>标签, 并为android:theme指定一个style名字, 比如:

<application android:theme="@style/CustomTheme">

如果我们想要这个theme应用于单个的Activity, 那么只需要为<activity>增加android:theme属性即可.

就好像Android提供的其它内置资源一样, 我们也同样有很多内置的theme可以使用. 比如我们可以使用Dialog theme使Activity以dialog的形式显示:

<activity android:theme="@android:style/Theme.Dialog">

或者如果我们想要使背景透明, 可以使用半透明(Translucent)主题:

<activity android:theme="@android:style/Theme.Translucent">

如果我们喜欢某个主题, 但是想改造它, 那么只需要将该主题作为parent再自定义自己的主题就可以了, 比如我们可以修改traditional light theme来使用我们自己的颜色:

<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>

需要注意这里的color资源需要作为一个独立的资源, 因为android:windowBackground属性只支持使用其它的资源, 不像android:colorBackground,它不能直接使用#b0b0ff这样的文本形式. 然后我们就可以使用我们的CustomTheme代替Theme.Light了:

<activity android:theme="@style/CustomTheme">

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

新版本的Android通常会提供新的主题, 如果我们希望自己的APP可以使用这些主题, 并且在旧版本的Android上也可以表现良好的话, 那么我们可以考虑基于平台版本来改变APP的主题. 比如这里是一个自定义主题的声明, 它只是简单的继承了Android内置的Theme.Light主题, 它将会存放在res/values目录下(通常是res/values/styles.xml):

<style name="LightThemeSelector" parent="android:Theme.Light">
    ...
</style>

我们又想要在Android3.0及以上版本的时候使用Holo主题, 那么我们可以在res/values-v11目录中添加一个额外的theme文件, 但是使用Holo作为parent:

<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
    ...
</style>

这样我们的theme就可以在Android3.0及以上版本中自动使用Holo主题了. 可以在R.styleable.Theme中查找在theme中可用的标准属性.

使用内置的style和theme:

Android为我们提供了大量的可用的style和theme. 我们可以在R.style中查找可用的style. 想要使用任何一个内置的style,只需要将它们名字中的下划线换成圆点就可以了, 比如我们可以通过”@android:style/Theme.NoTitleBar”来使用Theme_NoTitleBartheme.

由于R.style中的文档描述的并不咋好, 所以官方建议我们通过阅读style的源码来了解它们都提供了什么属性, 这里是源码的地址:

AndroidStyles(style.xml)

AndroidThemes(themes.xml)

这些文件将会帮我们学习里面的栗子, 比如在android theme的源文件中我们将会找到<style name=”Theme.Dialog>的声明, 在这里将可以看到所有应用于styledialog的属性.

 

总结:

我们可以通过style和theme为Android指定统一的风格. 它们都是style, theme是应用于Activity或者application的style.

使用流程: 首先在res/values/下简历styles.xml文件, 然后在layout中引用它们, 如果想要应用于整个Activity或者application则需要在manifest文件中指定android:theme属性.

 

参考: http://developer.android.com/guide/topics/ui/themes.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值