android 中的Style、Themes以及attr

声明:本文主要是参考 android官方API说明文档来的。

在开篇先说明下,本篇中所说的样式不是指Style,样式包括Style和Theme。Style和Theme都是定义样式的,只不过Style是作用在View或者Window上的,而Theme是作用在Activity或者Application上的。

==================分割线==Sytle And Theme=============================


一.Style ,是View或者Window的look和format的属性集合。样式可以指定如高度,填充,字体颜色,字体大小,背景颜色等等属性。样式是在一个XML资源,是独立于Layout XML资源的。

举例:使用Style之前的布局

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="#00FF00"
    android:typeface="monospace"
    android:text="@string/hello" />

使用Sytle之后:

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

所有涉及到的样式属性已经从布局XML中除去并放入一个CodeFont Style中,然后将其与样式属性应用。下面展示如何定义Style。

在这里说一下 Theme和Style的区别,Theme是应用于整个Activity或Application,而不是应用在一个单独的View(如上面的例子)上。当一个样式声明成Theme时,在Activity或者Application中的View都将应用它所支持的样式属性,比如如果将CodeFont样式声明成Theme并应用到Activity上,那么Activity所包含的所有文本都会是 CodeFont中定义的 绿色等宽的

-------------------------------------------------------小分割线--------------------------------------

1.定义Style

在 工程的res/values目录下定义 .xml文件  xml的根元素是 <resources> ,对于你想创建的每一个Style,添加<style>元素与唯一标识该样式的名称(必须有点的),然后添加一个<item>元素为该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>

这个是CodeFont的Style文件。

每个resources的子元素都会在编译时编译成程序的资源文件,可以通过style的 name属性值来引用。这个例子就是在layout的 XML文件中通过 @style/CodeFont来引用的样式资源。

在<style>元素的parent属性是可选的,指定继承自另一个Style的ID。然后,您可以重写继承的样式属性,如果你想。

------------------------下面详细解说下样式的继承问题-----------------------------------------

你可以用它来从现有样式继承属性,然后可以修改继承来的属性或者添加新的属性样式。你可以继承自你自己定义的样式或者系统内置的样式,例如,你可以继承Android平台的默认文本外观,然后修改它:

 <style name="GreenText" parent="@android:style/TextAppearance">
        <item name="android:textColor">#00FF00</item>
    </style>
如果只是继承自 自己定义的样式,就不需要parent属性来声明,只是这样就可以了:

    <style name="CodeFont.Red">
        <item name="android:textColor">#FF0000</item>
    </style>
这个就是一个新的样式,名称是 CodeFont.Red ,CodeFont是要继承的自定义的样式,Red是这个样式的名称,中间用“.”隔开就行。引用的时候按照@style/name 来就行了,此style的引用是这样的 @style/CodeFont.Red。

以此类推,如果需要有一个新的样式继承自 CodeFont.Red,只需要这样 :

    <style name="CodeFont.Red.Big">
        <item name="android:textSize">30sp</item>
    </style>
注意:只能这样继承自 自定义的样式,不能这样继承自系统内置样式,继承系统内置样式必须通过 parent属性来指定。

2.Style属性

android中所有样式属性都可以在 R.attr中找到!

现在您已经了解如何定义样式,现在需要知道什么样的样式能够在item元素中添加呢。你可能熟悉一些已经如layout_width和文字颜色。当然,也有有很多更多的样式属性,您可以使用。

要找到适用于特定视图属性最好的地方是对应的类的参考,其中列出了所有支持的XML属性。例如,所有在TextView的XML属性表中列出的属性可以用在样式定义一个TextView元素(或它的子类)中的一个参考列出的属性是android:inputType,所以在那里你可能通常放置在android:inputType属性在<EditText>元素,就像这样:

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

您可以改为创建包含此属性的EditText上元素的样式:

<style name="Numbers">
  <item name="android:inputType">number</item>
  ...
</style>
然后在XML布局文件中这样调用:

<EditText
    style="@style/Numbers"
    ... />
如果对View应用的样式中有View不支持的属性(对于所有可用的样式属性的请参考R.attr引用),那么View会自动忽略样式中不支持的属性而只加载View所支持的属性。View不会同时应用两个同名的属性,最新的属性会覆盖掉老的属性。

一些属性是只支持Activity或者Application的,例如,主题样式属性,可以隐藏应用程序的标题,隐藏状态栏,或者改变窗口的背景下,这些类型的样式属性不属于任何View对象。要发现这些主题样式属性,在R.attr中看看为开头为window的样式属性,比如,windowNoTitle和windowBackground,这些样式属性可以隐藏应用程序标题,隐藏状态栏,或者改变窗口的背景下,这些类型的样式属性不属于任何View对象,而是一个Activity或应用程序的主题。

注意:不要忘了在每个<item>标签中使用 Android:namespace来指定属性,例如:<item Name="android:inputType">。


二、Theme

其实Theme就是Style,只是叫法和引用的时候不一样。

引用区别如下:

①到单个视图中,通过添加style属性到XML为布局视图元素,style="@style/CodeFont";

②对Activity或者Application引用style像这样:添加android:theme属性到 <Activity>或者<Application>标签中。



======================对UI使用style和theme=================

当对一个单独的View设置style时,该style的属性只是作用于此单独的View;对ViewGroup设置style时,ViewGroup的自View不会继承ViewGroup的style,style也只是作用月ViewGroup。如果要让所有View继承style的属性,可以把style声明给Application的 theme属性,这样整个app中的所有View都会继承style中的属性样式,把style设置给Activity的话,该Activity包含的所有View都会继承style中的属性样式。

1.给View设置style

<TextView
    style="@style/CodeFont"
    android:text="@string/hello" />
注意:style不需要android命名空间。

2.给Activity或者Application设置theme

设置theme给所有Activitys,这样:

<application android:theme="@style/CustomTheme">
如果只是给单独的Activity设置theme,这样:

<activity android:theme="@android:style/Theme.Dialog">
如果你喜欢一个系统内置的主题,但是个别部分需要调整,只需要自定义一个style然后添加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 的值只支持引用,不支持直接指定颜色值。

现在引用CustomTheme来代替Theme.Light:

<activity android:theme="@style/CustomTheme">
--------------------小分割线------------------------------------------------

根据系统版本来选择主题:

在较新版本的android中,添加了新的主题样式,但是你的app需要运行在低版本的系统中。你可以自定义主题然后让资源文件在不同的系统版本间切换达到这一点。例如,在res/values (通常是res/values/styles.xml)定义:

<style name="LightThemeSelector" parent="android:Theme.Light">
    ...
</style>
当app运行在3.0或者更高版本上时,你可以在 res/values-v11声明一个备选主题

<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
    ...
</style>
然后在AndroidManifest.xml中的 <Application>或者<Activity>标签下声明android:theme="@style/LightThemeSelector",当app运行在不用的android版本上是,主题会自动切换到相应的主题。

--------------------小分割线------------------------------------------------

使用android内置的Styles和Themes

Android平台提供了非常多的的style和theme,你可以在你的应用程序中使用,你可以找到在R.style类中的所有可用style的参考。例如,你可以声明 通过继承"@android:style/Theme.NoTitleBar"来定义Theme_NoTitleBar主题。

可以通过下面的连接来查看android内置的所有style和theme:

注意:其实上面的Styles和Themes都是用<style>来定义的,只是Styles定义的内容比较少,一般适合应用给View,而Themes中定义的比较多和全一般就把整个app的风格都定义出来了,适合应用给Activity或者Application。


=====================大分割线==========================

这次来说说android 下的 attr。

attr是attribute的缩写,就是属性的意思,说白了就相当于给java中类的属性(属性名称,属性类型)。只是在编译时会自动在R.java(其实就是一个java类,会把资源文件中的资源写进这个类中,不同种类的资源生成不同的静态内部类,然后将不同种类资源中的每个资源在相应的静态内部类中生成final static 变量并赋值)文件中生成对应的类和类的变量。

我们在xml中定义的布局文件时,给View指定的属性例如,android:layout_width="wrap_content" ,其中android是命名空间(android代表android系统内置的属性当然也可以自定义attr),layout_width是 attr中的一个属性名,wrap_content是attr 属性名为layout_width的一个值(在定义attr时能够指定值的类型和取值规则);下面是一个自定义attr的例子:

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <attr name="attrib1" format="string" />
   <declare-styleable name="blahblah">
       <attr name="attrib2" format="string" />
       <attr name="guidelines">
            <enum name="on" value="2" />
            <enum name="onTouch" value="1" />
            <enum name="off" value="0" />
       </attr>
   </declare-styleable>
</resources>

然后就可以在布局 xml文件中引用这些attr了:

<com.xcar.activity.view.slidingmenu.SlidingMenu
        xmlns:sliding="http://schemas.android.com/apk/res/com.xcar.activity"
        android:id="@+id/slidingmenulayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        sliding:behindOffset="0dip"
        sliding:behindScrollScale="0"
        sliding:shadowDrawable="@drawable/brand_car_handle_shap"
        sliding:shadowWidth="5dip"
        sliding:touchModeAbove="margin"
        sliding:touchModeBehind="margin"
        sliding:viewAbove="@layout/car_brand_above"
        sliding:viewBehind="@layout/car_brand_behind" >
</com.xcar.activity.view.slidingmenu.SlidingMenu>

首先声明一个命名空间:sliding,这个名字是随便起的;然后在需要用到自定义attr的地方调用 --sliding:attr名称--  就可以了。然后在View的构造函数中拿到 attr,接着解析attr中的值来对View进行相应变量进行赋值以便在后续代码中使用。

注意:在自定义attr文件中有两种类型的 attr,attrib1是直接放到跟标签下的,而其他的则是放到了

declare-styleable 标签下,具体区别见:http://www.cnblogs.com/wangfenjin/archive/2012/09/05/2672007.html


-------------小分割线------------------------------
下面结合style和attr来解析下style的原理,对View应用style就相当于把style中定义的属性结合整个复制到View下,例如,

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

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="#00FF00"
    android:typeface="monospace"
    android:text="@string/hello" />
如果style中定义的属性和 在TextView直接定义的属性有相同的,那么新定义的属性就覆盖掉style中的属性。


通过上述描述,也就不难理解下面的写法了,

自定义attr如下:

 

 <?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- View styles -->
    <attr name="textTitle" format="reference" />
    <attr name="textBody" format="reference" />
    <attr name="buttonText" format="reference" />
    <attr name="radioButtonText" format="reference" />
    <attr name="backgroundTheme" format="reference"></attr>
    <attr name="attrib1" format="string" />
</resources>

布局文件如下:

<LinearLayout 
style="?backgroundTheme"
android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >


其实说白了,style就是属性的一个集合。上例中还有一个比较特殊的地方就是:style="?backgroundTheme" 而backgroundTheme只是一个属性,它值的格式是 reference 是引用型的。在这里style将属性backgroundTheme搬了过来属性的具体值则由它上层的Theme指定,如下我们再写三个style:

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

2.<style name="background_default">
      <item name="android:background">@drawable/background</item>
      <item  name="android:padding">2dp</item>
</style>

3.<style name="Theme.DefaultText">
      <item name="backgroundTheme">@style/background_default</item>

</style>



然后将Theme.DefaultText设置给Activity或者Application作为Theme,这样LinearLayout的样式就出来了,相当于:

<LinearLayout 

     <!--style="?backgroundTheme"-->

     android:background="@drawable/background"

     android:padding="2dp"

     android:layout_width="fill_parent"

     android:layout_height="fill_parent"
     android:orientation="vertical" >


完。

这里再不补充一点,利用自定义 attr 可以给在layout的xml文件中给View的属性设置“变量”。接着上面举例:

<LinearLayout 

     android:background="?attr/backgroundTheme"

     android:padding="2dp"

     android:layout_width="fill_parent"

     android:layout_height="fill_parent"
     android:orientation="vertical" >

然后,在style中更改  backgroundTheme的值,就能实现切换主题的功能了!



















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值