Android编程权威指南(第二版)学习笔记(二十)—— 第20章 样式与主题
2017-01-31 15:00
369 查看
本章主要讲了如何使用样式与主题(style and theme),使应用界面统一化标准化。
GitHub 地址:
完成第20章
那么使用这个样式的组件就会自动套用这个属性:
继承方式二:用指定父样式的方法继承
这个时候主题就可以派上用场了。可以把主题看作样式的进化加强版,同样是定义一套公共主题属性,样式属性需要逐个添加,而主题属性则会自动应用于整个应用。主题属性能引用颜色这样的外部资源,也能引用其他样式。使用主题,可以简单地说:“所有按钮都使用这个样式。”再也不用找到每个按钮,告诉它们要用哪个主题了。
在 manifest 文件中我们看到整个应用的主题是
AppCompat 库自带三大主题:
- Theme.AppCompat——深色主题
- Theme.AppCompat.Light——浅色主题
- Theme.AppCompat.Light.DarkActionBar——带深色工具栏的浅色主题
我们把 AppTheme 的父主题修改为 Theme.AppCompat,以便于修改属性。
colorPrimary 属性主要用来设置工具栏背景色。由于应用名称是显示在工具栏上的,colorPrimary 也可以称为应用品牌色
colorPrimaryDark 用于屏幕顶部的状态栏。从名字可以看出,它是深色版 colorPrimary。 注意,只有 Lollipop 以后的系统支持状态栏主题色。对于之前的系统,无论指定什么主题色,状态栏都是不变的黑底色。
最后,将 colorAccent 设置为灰色的。这个主题色应该和 colorPrimary 形成反差效果,主要用于给 EditText 这样的组件着色。
例如,我想找到设置页面背景颜色的属性(随着时间的推移,主题继承关系和层次可能有变,但下面介绍的方法不会变。 想要知道该覆盖哪个属性,就沿着继承树找吧!):
为什么要生成一个空主题,而不在 manifest 中直接使用
我们继续往上找。
要进入上一层时,可以看到有好几个候选的父主题,这里我们选择 values-v21 目录下的父主题
那就再往上走
但是没有我们想要的设置背景的属性,所以要继续往上
继续往上,这里
所以,最后我们可以在 AppTheme 中覆盖这个属性,设置背景颜色:
这样,我们的 BeatBoxButton 可以继承
在 XML 中引用具体值时(如颜色值),我们使用@符号。比如 @color/gray 指向某个特定资源。
在主题中引用资源时,我们使用?符号。
比如:
GitHub 地址:
完成第20章
1. 样式(Style)
1.1 样式的定义
样式是一组能应用于视图组件的属性,用于复用相同的 UI 特性
例如我们在 res/values/style.xml 中定义一个样式:<style name="BeatBoxButton"> <item name="android:background">@color/dark_blue</item> <!--其中的 color 资源在 colors.xml 中定义--> </style>
那么使用这个样式的组件就会自动套用这个属性:
<Button …… style="@style/BeatBoxButton" <!--这样就能自动套用这个背景的颜色--> ……/>
1.2 样式的继承
样式的继承可以在原有样式的基础上添加和覆盖属性
继承方式一:通过命名表示样式继承关系<!--用点连接表示继承关系,只能在包内使用--> <style name="BeatBoxButton.Strong"> <item name="android:textStyle">bold</item> </style>
继承方式二:用指定父样式的方法继承
<!--用 parent 属性表示继承关系,可以跨库使用--> <style name="StrongBeatBoxButton" parent="@style/BeatBoxButton"> <item name="android:textStyle">bold</item> </style>
2. 主题(Theme)
样式能让一些属性复用,看上去节省了许多工作,在 styles.xml 公共文件中,可以为所有组件定义一套样式属性共用。然而,如果组件多了,需要逐个为所有组件添加它们要用到的样式,工作量是很大的。这个时候主题就可以派上用场了。可以把主题看作样式的进化加强版,同样是定义一套公共主题属性,样式属性需要逐个添加,而主题属性则会自动应用于整个应用。主题属性能引用颜色这样的外部资源,也能引用其他样式。使用主题,可以简单地说:“所有按钮都使用这个样式。”再也不用找到每个按钮,告诉它们要用哪个主题了。
2.1 主题属性的更改
主题作用于某个 activity 或者整个应用,这和主题在 manifest 文件中的声明位置有关,如果在<application>标签中声明,则是作用于整个应用,在
<activity>标签中声明,则是作用于单个 activity。
在 manifest 文件中我们看到整个应用的主题是
android:theme="@style/AppTheme",按住 Command(Windows 下是 Ctrl),点击 AppTheme 就可以进入其声明的位置,可以看到以下代码:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> </style>
AppCompat 库自带三大主题:
- Theme.AppCompat——深色主题
- Theme.AppCompat.Light——浅色主题
- Theme.AppCompat.Light.DarkActionBar——带深色工具栏的浅色主题
我们把 AppTheme 的父主题修改为 Theme.AppCompat,以便于修改属性。
2.1.1 修改主题颜色
在空空的主题 style 标签中加入几个属性,如下:<style name="AppTheme" parent="Theme.AppCompat"> <item name="colorPrimary">@color/red</item> <item name="colorPrimaryDark">@color/dark_red</item> <item name="colorAccent">@color/gray</item> </style>
colorPrimary 属性主要用来设置工具栏背景色。由于应用名称是显示在工具栏上的,colorPrimary 也可以称为应用品牌色
colorPrimaryDark 用于屏幕顶部的状态栏。从名字可以看出,它是深色版 colorPrimary。 注意,只有 Lollipop 以后的系统支持状态栏主题色。对于之前的系统,无论指定什么主题色,状态栏都是不变的黑底色。
最后,将 colorAccent 设置为灰色的。这个主题色应该和 colorPrimary 形成反差效果,主要用于给 EditText 这样的组件着色。
2.2 主题的抽丝剥茧
完成了主题配色,我们继续来点深入的,比如可以看看可以覆盖的主题属性都有哪些。在研究诸如有哪些主题属性可用,哪些能覆盖,甚至是有某些属性究竟有什么作用等这样的问题时,几乎没有官方参考文档可以参考,所以要逐级往上查看。例如,我想找到设置页面背景颜色的属性(随着时间的推移,主题继承关系和层次可能有变,但下面介绍的方法不会变。 想要知道该覆盖哪个属性,就沿着继承树找吧!):
第一层
也就是 AppTheme 主题,它原本是个 Android Studio 自动生成的空的主题。为什么要生成一个空主题,而不在 manifest 中直接使用
Theme.AppCompat.Light.DarkActionBar呢?这就是设计模式的事情了,对于应用本身来说,使用的主题不管父主题是谁,引用的都是 AppTheme 这个主题,相当于定义主题的时候留出了一个 AppTheme 的接口。对于协作开发来说,你不用管我内部如何实现也不用操心该怎么引用,只要使用 AppTheme 就够了。
我们继续往上找。
第二层
进入Theme.AppCompat,可以看到其也是一个空主题:
<style name="Theme.AppCompat" parent="Base.Theme.AppCompat"/>
要进入上一层时,可以看到有好几个候选的父主题,这里我们选择 values-v21 目录下的父主题
第三层
这一层仍然是空主题<style name="Base.Theme.AppCompat" parent="Base.V21.Theme.AppCompat"/>
那就再往上走
第四层
终于出现了很多属性< b99f ;style name="Base.V21.Theme.AppCompat" parent="Base.V7.Theme.AppCompat"> …… </style>
但是没有我们想要的设置背景的属性,所以要继续往上
第五层
也定义了很多属性,但是也没有需要的<style name="Base.V7.Theme.AppCompat" parent="Platform.AppCompat"> …… </style>
继续往上,这里
Platform.AppCompat也有多个版本,我们选择 values-v11 下的父主题
第六层
空主题,继续往上<style name="Platform.AppCompat" parent="Platform.V11.AppCompat"/>
第七层
终于看到了我们想要的属性:<!--可以看到这个主题的 parent 是带有 android 命名空间的,表示其来源于 Android 系统--> <style name="Platform.V11.AppCompat" parent="android:Theme.Holo"> …… <!-- Window colors --> …… <item name="android:colorBackground">@color/background_material_dark</item> …… </style>
所以,最后我们可以在 AppTheme 中覆盖这个属性,设置背景颜色:
<item name="colorBackground">@color/soothing_blue</item>
2.3 修改按钮颜色
同样的,我们再往上找,能在android:Theme.Holo中找到 buttonStyle 属性:
<item name="buttonStyle">@style/Widget.Holo.Button</item>
这样,我们的 BeatBoxButton 可以继承
Widget.Holo.Button这个样式,然后在 AppTheme 中使用 buttonStyle 属性。
3. 引用主题属性
在主题中定义好属性后,可以在 XML 或代码中直接使用它们。在 XML 中引用具体值时(如颜色值),我们使用@符号。比如 @color/gray 指向某个特定资源。
在主题中引用资源时,我们使用?符号。
比如:
<Button xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/list_item_sound_button" android:layout_width="match_parent" android:layout_height="120dp" android:background="?attr/colorAccent" tools:text="Sound name"/>
4. 挑战练习
新建 values-v21 下的 styles.xml 文件,继承自 Widget.Material.Button 即可相关文章推荐
- Android编程权威指南(第二版)学习笔记(二十九)—— 第29章 定制视图与触摸事件
- Android编程权威指南(第二版)学习笔记(四)—— 第4章 Android 应用的调试
- Android编程权威指南(第二版)学习笔记(八)—— 第8章 使用布局与组件创建用户界面
- Android编程权威指南(第二版)学习笔记(十三)—— 第13章 工具栏(Toolbar)
- Android编程权威指南(第二版)学习笔记(二十一)—— 第21章 XML drawable
- Android编程权威指南(第二版)学习笔记(二十六)—— 第26章 后台服务
- Android编程权威指南(第二版)学习笔记(十二)—— 第12章 对话框
- Android编程权威指南(第二版)学习笔记(二十三)—— 第23章 HTTP 与后台任务
- Android编程权威指南(第二版)学习笔记(二十二)—— 第22章 深入学习 intent 和任务
- Android编程权威指南(第二版)学习笔记(十五)—— 第15章 隐式 Intent
- Android编程权威指南(第二版)学习笔记(十七)—— 第17章 Master-Detail 用户界面
- Android编程权威指南(第二版)学习笔记(二十五)—— 第25章 搜索
- Android编程权威指南(第二版)学习笔记(二十八)—— 第28章 网页浏览
- Android编程权威指南(第二版)学习笔记(二)—— 第2章 Android 与 MVC 设计模式
- Android编程权威指南(第二版)学习笔记(三)—— 第3章 日志跟踪理解 Activity 生命周期
- Android编程权威指南(第二版)学习笔记(十一)—— 第11章 使用 ViewPager
- Android编程权威指南(第二版)学习笔记(十八)—— 第18章 Assets
- 自定义view的构造方法和样式主题
- android 主题和样式-style和Theme的区别和使用
- APP主题样式大全