一、Attr

属性,风格样式的最小单元;

Attr 的定义

在自定义 View 的时候,在 res/attrs.xml 文件中声明属性,而Android 系统的属性也是以同样的方式定义的。
比如 layout_width 属性对应到框架中的 attr 如下:

<declare-styleable name="ViewGroup_Layout">
<attr name="layout_width" format="dimension">
<enum name="fill_parent" value="-1" />
<enum name="match_parent" value="-1" />
<enum name="wrap_content" value="-2" />
</attr>
...
</declare-styleable>

attr 的 format 有以下几种格式,可以进行或运算:
color、reference、boolean、dimension、enum、flag、float、fraction、integer、string
这里着重说一下 enum 是枚举值,而 flag 可以进行或运算,属性值可以叠加使用,
reference 用在一些可以设置引用值的情况,引用 res 资源
fraction 是百分数的意思

二、Style

风格,它是一系列Attr的集合,用以定义一个View的样式;
style 是定义在 res/styles.xml 文件中的,在控件中使用时只需要style="@style/style_name"就可以使用样式了。
我们在自定义 View 时通过
·obtainStyledAttributes( AttributeSet set, @StyleableRes int[] attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes)
方法获取自定义的
attr ,其中第一个参数表示是 xml 文件解析后得到的属性集合,attrs 是 View 声明的属性集,后两个用作指定默认的
Style,表示如果 set 中没有你想获得的属性,但如果你指定了默认 Style,它会去从该默认的 Style
里面找你想要的属性。defStyleAttr 和 defStyleRes 功能一样,指定的资源形式不同,前者表示一个默认的指向一个 style
风格的 attr 属性,而后者你可以直接传入一个 style 风格的 id。

三、Theme

主题,它与Style作用一样,都是一系列属性的集合,不同于Style作用于一个单独View,而它是作用于Activity上或是整个应用;与
Window 有关的属性作用于 Window,与 View 有关的属性作用于 Activity 的所有 View 或者整个应用的所有
View,如果想要改变 Window 的属性,那么继承相应 Theme,重写属性值,如果想要改变 View 相关样式,在 Theme
中重写属性作用于整个 Activity 或整个应用,或者定义 style 作用于单个 View。
Theme 的实质也是
Style,Theme 的定义格式与 Style 的基本一致,Theme 需要设置到 AndroidManifest.xml 的
<application> 或者 <activity> 标签下,设置后,被设置的 Activity 或整个应用下所有的
View 都可以使用该 <style> 里面的属性了。
style 除过有 name 属性以外还可以有 parent
属性,一般在 style 中使用 parent 字段的继承适用于继承系统平台现有定义的 style,想要继承自己实现的 style
一般不会通过parent字段来实现,而是通过指定格式的 name 字段来实现。
Theme 中以 windowXXX 开头的属性就不适用于 View,但是不会报错,只是 View 会忽略这些不适合自己的属性,应用适合自己的属性。

四、Theme 兼容性处理

Google官方提供Android Support Library package来保证高版本SDK的向下兼容。

  • v4 Support Library
    此包用在API lever 4(即Android
    1.6)及更高版本之上。它包含了较多的内容,使用非常广泛,例如:Fragment,NotificationCompat,LoadBroadcastManager,ViewPager,PageTabStrip,Loader,FileProvider
    等。
  • v7 Support Libraries
    此包是针对API level 7(即Android 2.1)及以上版本而设计的,但是v7是要依赖v4这个包的,v7支持了Action Bar以及一些Theme的兼容。
    v7 appcompat library 是包含在 v7 Support Libraries里面的一个包,正是此包增加了Action Bar 用户界面的设计模式,并加入了对material design 的支持,是我们使用最多的一个兼容包。

Android 系统有三个基本主题:

  • android:Theme
  • android:Theme.Holo
  • android:Theme.Material
  • Theme.AppCompat

android:Theme是所有主题的超级父类。所有的主题都是直接继承或者间接继承它。
android:Theme.Holo 从 Api 11开始可以使用。android:Theme.Material 从 Api 21开始可以使用。
如果要在不同版本的系统上用各自的主题,比如在4.0之下的系统用android:Theme,4.0至5.0的系统用Holo主题,5.0及之后的系统使用Material

Design,那我们需要建不同的value-vX目录。在各自的目录中的style继承相应的系统主题。在运行是系统就会根据平台版本使用相应的主题。
如果只创建一个
value 文件的话,那么系统的版本可能会不支持 value 中继承的主题,系统就会根据 App 指定的 targetSdkVersion
自动设置主题,如果设置的 targetSdkVersion 还是高于系统的版本,系统就设置为支持的最高系统 sdk 版本的主题。
具体是怎么选择的呢?我们来看 Resources 类中的源码

 public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {
return selectSystemTheme(curTheme, targetSdkVersion,
com.android.internal.R.style.Theme,
com.android.internal.R.style.Theme_Holo,
com.android.internal.R.style.Theme_DeviceDefault,
com.android.internal.R.style.Theme_DeviceDefault_Light_DarkActionBar);
} /** @hide */
public static int selectSystemTheme(int curTheme, int targetSdkVersion, int orig, int holo,
int dark, int deviceDefault) {
if (curTheme != 0) {
return curTheme;
}
if (targetSdkVersion < Build.VERSION_CODES.HONEYCOMB) {
return orig;
}
if (targetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return holo;
}
if (targetSdkVersion < Build.VERSION_CODES.CUR_DEVELOPMENT) {
return dark;
}
return deviceDefault;
}

我们可以看到当 targetSdkVersion 低于11时,选择 Theme 主题、当 targetSdkVersion 低于 14 时,选择 Theme.Holo 主题,当 targetSdkVersion 高于 14 时,选择 Theme.DeviceDefault,而 Theme.DeviceDefault 继承自 Theme.Material。
如果我们想在 5.0 以下的系统中使用 Material
主题,只需要让我们的系统主题继承Theme.AppCompat即可。当然需要导入support-v7 appcompat
包,可以在sdk\extras\android\support\v7\appcompat 查看到。使用了 Theme.AppCompat
之后,就不受 targetSdkVersion 影响了。
AppCompatActivity(包括 ActionBarActivity)的子 Activity 必须使用 Theme.AppCompat 或 Theme.AppCompat 的子主题,如果不是,编译时不会给出任何警告,但运行时会抛出异常。

五、Android 系统预制的 Theme 和 Style

我们想要知道系统的 Theme 有哪些属性可以使用,系统为我们提供了哪些 Style 可以使用,可以到
sdk\platforms\android-24\data\res\values 文件夹下去查看 styles.xml 和 theme.xml
文件中去查看,以 Theme 为例,一个完整的主题需要定义颜色、Text 样式、Button 样式、List 属性、Window
属性、Dialog 属性、AlertDialog 属性、Panel 属性、ScrollBar 属性、文字选中属性、Widget
样式、Preference (设置类界面)样式、Search Widget 样式、ActionBar
样式等。我们可以发现这些属性的值有些是具体的值,有些是引用的 android:color、android:drawable
等系统资源,有些是引用的系统中所定义的样式 android:style,有些则是直接引用系统主题中所定义的其它属性?android:attr
1、我们可以根据这些属性修改系统提供的控件样式和窗体样式;
2、我们可以引用系统主题的属性值;

六、Android应用资源拓展语法

Theme 和 Style 的实质都属于 res 资源,和其它资源类型如 drawable、layout、dimen 等的引用方式是一样的。
Android 中资源在Java文件中引用的语法定义如下:

[包名.]R.<资源类型.><资源名>
//当资源在当前应用中则包名可以省略,当为系统的资源则可换为 android.

Android 资源在XML文件中引用的语法定义如下:

@[包名:]<资源类型/><资源名>
//当资源在当前应用中则包名可以省略,当为系统的资源则换为 android.

Android系统预制资源在XML文件中引用的特殊语法定义如下:

//可以引用系统所有资源,public & private
@*android:type/name
//只能引用系统public的资源
@android:type/name

Android在XML文件中引用当前主题属性的语法定义如下:
资源值允许引用当前主题中的属性的值,这个属性值只能在style资源和XML中使用,随着当前主题的切换该值也在变换

?[<包名>:][<资源类型>/]<资源名>
//如果是本应用中的attr使用,则可以省去<package_name>部分。

Android在XML文件中创建或者引用资源语法定义如下:

//在R.java的type内部类中添加一条静态常量id资源标识符,如果标示符(包括系统资源)已经存在则表示引用该标示符。
@+type/name //在R.java中寻找已经定义的标识符,如果找不到则提示失败错误,一般在xml中定义有先后关系。
@type/name

Android在XML文件中xmlns语法定义如下:

xmlns:namespace-prefix=http://schemas.android.com/apk/res/应用程序包路径

参考:
Attr、Style和Theme详解
Android主题和样式之系统篇(上)
Android主题和样式之系统篇(下)
Android开发之Theme、Style探索及源码浅析
Android关于Theme.AppCompat相关问题的深入分析
Android的系统主题总结

【Android】attr、style和theme的更多相关文章

  1. Android中style和theme的区别

    在学习Xamarin android的过程中,最先开始学习的还是熟练掌握android的六大布局-LinearLayout .RelativeLayout.TableLayout.FrameLayou ...

  2. Android中Style和Theme的使用

    Style: Style是View中一些属性的集合,包括height,padding,font color,background等等,Style单独定义在xml文件中,类似与web页面中css的角色, ...

  3. android的style控制Theme

    value-v14就是在API14(4.0)的手机上所使用的Theme(其他版本以此类推) theme的名字叫做AppTheme,后面写有继承自哪个Theme,如下所示 <style name= ...

  4. Android:Style和Theme

    在Web开发中,Html负责内容,CSS负责表现.同样,在Android开发中,可以使用Theme.Style+UI组件的方式实现内容和形式的分离. Style是针对窗体元素级别的,改变指定控件或者L ...

  5. Android入门第十六篇之Style与Theme [转]

    本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处! 越来越多互联网企业都在Android平台上部署其客户端,为了提升用户体验,这些客户端都做得布局合理而且美观.. ...

  6. 【转】说说Android中的style和theme

    最近在做软件从2.3到4.0的改变的一些工作,其中涉及了一些style和theme相关的东西.上网上查了一些东西,这个一并说说.关于android中style和theme的基本使用,这里就不再赘述了, ...

  7. 深入理解Android 自定义attr Style styleable以及其应用

    相信每一位从事Android开发的猿都遇到过需要自己去自定义View的需求,如果想通过xml指定一些我们自己需要的参数,就需要自己声明一个styleable,并在里面自己定义一些attr属性,这个过程 ...

  8. 【转】android中的Style与Theme

    Android默认情况下提供了一些实用的主题样式,比如说Theme.Dialog可以让你的Activity变成一个窗口风格,而Theme.Light则让你的整个Activity具有白色的背景,而不是黑 ...

  9. android UI进阶之style和theme的使用

    今天来和大家分享一下android中UI设计里面常会用到的style和theme. 首先,style和theme都是资源,android提供了很多这样的默认资源.你可以来使用它们.同时你也可以自己定义 ...

随机推荐

  1. 图说不为人知的IT传奇故事-2-IBM咬不动的胡桃

    此系列文章为“图说不为人知的IT传奇故事”,各位大忙人可以在一分钟甚至几秒内了解把握整个内容,真可谓“大忙人的福利”呀!!希望各位IT界的朋友在钻研技术的同时,也能在文学.历史上有所把握.了解这些故事 ...

  2. editrules

    editrules    editrules是用来设置一些可用于可编辑列的colModel的额外属性的.大多数的时候是用来在提交到服务器之前验证用户的输入合法性的.比如editrules:{edith ...

  3. java读取文件(更新jdk7及jdk8)

    以字节的方式读取: InputStream inputStream = new FileInputStream(file); int temp = -1; StringBuilder sb = new ...

  4. 团队Alpha版本冲刺(二)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内 ...

  5. Python机器学习数据挖掘工具sklearn安装和使用

    python借助pip安装第三方库,所以首先确保电脑上已成功安装了pip. 安装sklearn前需要先安装numpy.scipy和pandas等库.安装的方式有两种: 一.前往python的组件库页( ...

  6. top/free/df/jstack/jmap

    上面的输出,load average后面分别是1分钟.5分钟.15分钟的负载情况.数据是每隔5秒钟检查一次活跃的进程数,然后根据这个数值算出来的.如果这个数除以CPU 的数目,结果高于5的时候就表明系 ...

  7. Emma中文乱码解决方法

    vim -/.emma/emmarc db_encoding=latin1 改为 db_encoding=utf8 sudo vim /usr/share/emma/emmalib/mysql_hos ...

  8. C#的一些基本问题

    静态类和静态变量静态类的定义:static class 类名 静态方法和变量必须使用类名来引用,而不能使用实例化后的对象,因为,静态变量不属于任何实例,而是共有的. 非静态类里面既可以定义静态方法也可 ...

  9. [luoguP2587] [ZJOI2008]泡泡堂(贪心)

    传送门 贪心,很像田忌赛马那样,但是因为有平局加一分导致那样的贪心不好处理. 先将两个数组从小到大排序. 比较a最大和b最大,如果a比b大,那么直接赢掉 否则 比较a最小和b最小,如果a比b大,那么直 ...

  10. jquery 实践操作:iframe 相关操作

    此篇记录关于HTML 的 iframe 元素 的相关记录 定义:iframe 元素会创建包含另外一个文档的内联框架(即行内框架). 常用的基本 iframe 设置(详细设置属性参考API:http:/ ...