Android 主题风格(Theme&Style)介绍
来源:互联网 发布:淘宝hd的微淘达人 编辑:程序博客网 时间:2024/06/07 09:40
使用 Style
Android 中的View、Window等控件通常会定义一些属性来表示各自的外观、格式等信息,例如一个TextView中的字体大小、字体颜色,一个Dialog的窗口类型、窗口大小等。而Style就是设置到一个View或者Window上的一系列属性的集合。我们可以将TextView的字体样式、字体颜色、字体大小等属性定义成一个Style,所有使用这个Style的TextView将会有相同的字体样式、字体颜色、字体大小。
Style一般是以xml文件的形式保存在资源目录中的,并且是与布局资源layout文件分离开来的,这样我们就可以将一套Style与使用这套Style的控件分离开来,进行独立维护,而且还可以将同一套Style复用到多个控件上,方便移植。从这一点上看Style有点类似于网页设计中的CSS,允许开发者将设计与内容分离。
下面是layout中一个TextView的定义,其中的typeface
、textColor
、textSize
几个属性是直接定义的:
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:typeface="monospace" android:textColor="#ffff00ff" android:textSize="24sp" android:text="@string/hello_world"/>
如果我们将这几个属性分离出来,定义成一个Style,就会是下面的样子:
Style:
<style name="CodeFont"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:typeface">monospace</item> <item name="android:textColor">#ffff00ff</item> <item name="android:textSize">24sp</item></style>
Layout:
<TextView style="@style/CodeFont" android:text="@string/hello_world" />
这样CodeFont
这个Style还可以应用到其他的TextView,而且只需要修改CodeFont
,所有使用这个Style的TextView都会改变样式。
使用 Theme
Theme其实就是应用到Activity或者Application上的Style。如上面我们刚刚定义的CodeFont
,还可以按下面的方式应用到Activity或者Application上。在AndroidManifest.xml
中可以如下设置:
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/CodeFont" > <activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/CodeFont" > ... <activity> ...</application>
如果Theme应用到Activity上,那么这个Activity中所有的View、Window都会使用Theme中定义的属性。同样,如果Theme应用到Application上,那么这个Application中所有的Activity中的View、Window都会使用Theme中定义的属性。
经过上面的介绍我们可以知道,Style和Theme的区别就在于应用的范围不同。Style是应用到单独的一个View上的,而Theme是应用到一个Activity或者Application中的View上的。
Style、Theme的继承性
Style是可以继承的,子Style可以继承父Style定义的属性,并重写父Style的属性。
如下面代码,Style CodeFont通过parent
属性继承自系统的Style TextAppearance
,并修改了textColor
、typeface
等几个属性,而其他没有修改的属性默认会使用TextAppearance中的定义。
<style name="CodeFont" parent="@android:style/TextAppearance"> <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>
而如果是想从自己定义的Style继承,可以不使用parent
关键字,而是把父Style名称做为子Style名称的前缀。如下面,CodeFont.Red
继承自CodeFont
,并修改了textColor
属性为#FF0000
:
<style name="CodeFont.Red"> <item name="android:textColor">#FF0000</item></style>
使用系统Theme
Android系统资源中已经定义了很多的Style和Theme,如Android 4.0之前使用的默认Theme,Android 4.0之后引入的Holo系列Theme,Android 5.0之后引入的Material系列Theme。我们可以在自己的应用中直接使用这些系统内置的Theme或者从这些Theme继承子Theme并进行修改。
上面介绍的Theme并不是支持Android所有的版本,如Holo风格的Theme只支持Android 4.0+的版本,Material风格的Theme只支持Android 5.0+的版本,那么我们想让我们的应用能够自己根据不同的Android版本适配不同的Theme呢?看下面:
AndroidManifest.xml
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > ...</application>
res/values/styles.xml
<style name="AppTheme" parent="@android:style/Theme"></style>
res/values-v14/styles.xml
<style name="AppTheme" parent="@android:style/Theme.Holo"></style>
res/values-v21/styles.xml
<style name="AppTheme" parent="@android:style/Theme.Material"></style>
我们先在默认的资源目录res/values/下定义了一个AppTheme
,继承自系统的默认Theme,在Android 4.0的资源目录res/values-v14/下面重新定义AppTheme
,并继承自Theme.Holo
,在Android 5.0的资源目录res/values-v21/下面重新定义AppTheme
,并继承自Theme.Material
,这样应用在Android 4.0之前的版本上运行时会使用默认Theme,在Android 4.0 ~Android 4.4版本上运行时会使用Holo主题,在Android 5.0+的版本上会使用Material主题。
定义 Style
前面了解了Styles都是在xml资源文件里定义的,那么在资源文件里定义的这些Styles最后是怎么应用到对应的View上的,而一个View的各个属性又是在哪里定义的呢?
我们先看一看Android系统资源的源码,没有源码的同学可以到http://androidxref.com/去看。
Android系统中定义的资源都是放在源码的frameworks/base/core/res目录里的,每个View属性都是定义在res/values/attrs.xml文件里的,如下面TextView
属性的定义:
frameworks/base/core/res/res/values/attrs.xml
<declare-styleable name="TextView"> ... <!-- Text to display. --> <attr name="text" format="string" localization="suggested" /> <!-- Hint text to display when the text is empty. --> <attr name="hint" format="string" /> <!-- Text color. --> <attr name="textColor" /> ...</declare-styleable>
这里为TextView
定义了一个<declare-styleable>
元素,也就是定义了一个Style。里面的每个<attr>
为TextView
定义了一个属性,如text
、hint
、textColor
等属性,format
表示该属性的格式,主要有以下几种:
14sp
,15dp
fraction 百分数资源,如20%
,30%p
enum 枚举型资源 flags 位标记资源解析Style
应用的编译过程中资源编译工具aapt会自动创建一个R.java文件,里面会为应用中所有的资源、属性定义一个ID。编译系统资源framework-res时也会生成一个R.java,里面会创建一个styleable
类来存放所有View的属性定义,如下面是上面看到的TextView
里定义的几个属性:
out/target/common/obj/APPS/framework-res_intermediates/src/android/R.java
public static final class styleable { ... public static final int TextView_text = 18; public static final int TextView_hint = 19; public static final int TextView_textColor = 5; ...}
在资源类R.java里text
、hint
、textColor
几个属性被定义成了TextView_text
、TextView_hint
、TextView_textColor
等的int型变量。那么这些变量是怎么使用的呢?
我们可以看一下TextView
构造方法里的代码:
frameworks/base/core/java/android/widget/TextView.java
CharSequence text = "";CharSequence hint = null;final Resources.Theme theme = context.getTheme();TypedArray a = theme.obtainStyledAttributes(attrs, com.android.internal.R.styleable.TextView, defStyleAttr, defStyleRes);int n = a.getIndexCount();for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { ... case com.android.internal.R.styleable.TextView_hint: hint = a.getText(attr); break; case com.android.internal.R.styleable.TextView_text: text = a.getText(attr); break; ... }}a.recycle();setText(text, bufferType);if (hint != null) setHint(hint);
- 这里先定义了text、hint两个字符串;
- 通过context.getTheme()得到一个Resources.Theme,这就是一个主题。;
- 通过theme.obtainStyledAttributes得到一个TypedArray,这是一个资源属性数组,包含这我们在Theme里定义的所有属性的值;
- 通过遍历TypedArray里的所有属性,找到TextView_hint、TextView_text属性对应的值,赋值给hint和text;
- TextView使用text、hint的值。
上面介绍的是Style和Theme的定义方法和使用原理,至于更深层次的资源解析方面的问题暂时不做讨论。
下面有一个主题切换的小Demo,有兴趣的可以看一下。
https://github.com/geyunfei/ThemeDemo
- Android 主题风格(Theme&Style)介绍
- android 主题theme风格style
- android主题theme和风格style总结
- Android风格与主题( style and theme )
- Android主题theme和风格style总结
- Android风格style与主题theme
- Android主题theme和风格style总结
- android风格和主题:Style and Theme
- Style(风格) 和 Theme(主题)
- android风格和主题程序编写–style & theme
- Android风格与主题(style and theme)
- Android风格与主题(style and theme)
- Android风格与主题(style and theme)
- Android风格与主题(style and theme)
- android之风格与主题(style与theme)
- Android 风格与主题(style and theme)
- Android风格与主题(style and theme)
- Android中的风格和主题(style和theme)
- Linux 16.04+Caffe+TensorFlow+CUDA9
- 20行 java回溯法 无优先级运算问题 含详细注释
- 升级tensorflow
- IT行业的风投
- transitionFromViewController方法的使用
- Android 主题风格(Theme&Style)介绍
- 爬虫抓取百度指数思路总结
- 关于sprintf函数详解
- VRTK交互脚本解析之VRTK_InteractableObject
- Android开发之gradle理解
- 使用scikit-learn的随机森林对西瓜进行分类
- Error:Execution failed for task ':app:packageDebug'解决方案
- python小爬虫(12306火车票)
- Hyperledger fabric mac 环境搭建 001