——读《Android变成权威指南》,总结摘录样式与主题章节,以便日后查找阅读
1. 样式
2. 主题
3. XML drawable
为什么使用XML drawable?
因为XML drawable 使用灵活方便,不仅用法多样,还易于更新维护,并且独立于屏幕像素密度。
样式是一套应用于视图组件的属性
<style name="BeatBoxButton" >
<item name="android:background">@color/dark_blue
style>
该样式仅定义了background属性,样式可以为很多组件共用,更新修改属性时,只修改公共样式就行。
定义好样式后,添加给各个按钮:
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list_item_sound_button"
**style="@style/BeatBoxButton"**
android:layout_width="match_parent"
android:layout_height="120dp"
android:text="Sound name"
android:textAllCaps="false">
样式继承:样式支持继承。一个样式能继承并覆盖其他样式的属性。
<style name="BeatBoxButton.Strong" >
<item name="android:textStyle">bolditem>
style>
除了通过命名表示样式继承关系,也可以采用指定父样式的形式:
<style name="StrongBeatBoxButton" parent="@style/BeatBoxButton">
<item name="android:textStyle">bolditem>
style>
可以为所有组件定义一套样式属性共用。可惜,定义公共样式属性虽然方便,实际应用却很麻烦:需要逐个为所有的组件添加他们要用到的样式。要是开发一个复杂应用,涉及很多布局无数按钮,仅仅添加样式就需要很大的工作量。
同样是定义一套公共主题属性,样式属性需要逐个添加,而主题属性则会自动应用于整个应用。
简单说:所有按钮都使用这个样式。再也不用找到每个按钮,告诉他们要用那个主题了。
主题实际就是一种样式,但是指定有别于样式,既然是在manifest文件中声明的他,自然就有了魔力。这也解释了为什么主题可以自动应用于整个应用。
样式属性:仅适用于单个组件
主题属性:适用于所有使用用同一主题的组件
比如修改应用背景色,你可以打开xml文件,手动设置视图的background属性。但这简直是浪费:浪费时间,浪费系统资源。主题已经设置了背景色,在此基础上在设置其他颜色,就是多出来在做额外的工作。而且到处复制使用背景属性设置代码也不利于后期维护。
具体操作:
在主题继承源头,找到要覆盖的的属性,比如colorBackground,这就是要在应用中覆盖的属性。
在主题中定义一个用于所有按钮的样式:
<Button
xmlns:android="http://schemas.android.com/apk/res/android";
xmlns:tools="http://schemas.android.com/tools";
android:id="@+id/list_item_sound_button"
~~style="@style/BeatBoxButton"~~
android:layout_width="match_parent"
android:layout_height="120dp"
android:text="Sound name"
android:textAllCaps="false">
删除原有样式
<style name="BeatBoxButton" parent="android:style/widget.Holo.Button">
<item name="android:background">@color/dark_blue
style>
修改父样式,复用Android自身主题。
继承android:style/widget.Holo.Button样式,就是首先让所有按钮都继承常规按钮的属性。然后根据需要,有选择性的修改一些属性。如果不指定父样式,所有的按钮会变得不再像个按钮,连中间文字都会消失。
样式已经定义完了,现在可以使用了。
运行应用,所有的按钮都改变了,而我们没有直接修改任何布局。
<shape
android:shape="oval">
<solid
android:color="@color/dark_red"/>
shape>
修改按钮背景,这是圆形的按钮已经出现了
<style name="BeatBoxButton" parent="android:style/widget.Holo.Button">
<item name="android:background">@color/dark_blue (delete)
- "android:background"
>@drawable/button_beat_box_normal (add)
style>
但是当按钮按下去的时候,如果可以切换状态,效果会更好。
使用state list drawable
为解决这个问题首先定义一个按钮按下状态的shape drawable
<shape
android:shape="oval">
<solid
android:color="@color/red"/>
shape>
接下来,要在按钮按下时使用这个新建的shape drawable。这需要用到state list drawable
<selector xmlns:android="http://schemas.android.com/apk/res/android";>;
<item android:drawable="@drawable/button_beat_box_pressed"
android:state_pressed="true"/>
<item android:drawable="@drawable/button_beat_box_norma"/>
selector>
主题引用这个布局文件
<style name="BeatBoxButton" parent="android:style/widget.Holo.Button">
<item name="android:background">@color/dark_blue (delete)
- "android:background"
>@drawable/button_beat_box_normal (delete)
- "android:background"
>@drawable/button_beat_box (add)
style>
按钮没有按下时使用normal做背景,按下时就是用pressed做背景。
layer list drawable
能让两个XML drawable合二为一,借助这个工具,可以为按下状态的按钮添加一个深色的圆环。
<layer-list xmlns:android="http://schemas.android.com/apk/res/android";>;
<item>
<shape
android:shape="oval">
<solid
android:color="@color/red"/>
shape>
item>
<item>
<shape
android:shape="oval">
<stroke
android:width="4dp"
android:color="@color/dark_red"/>
shape>
item>
layer-list>
现在,layer list drawable中指定了两个drawable,第一个时和以前一样的红圈,第二个则会绘制在第一个圈上它定义一个4dp的粗深红圆圈。