本文讲解安卓中 Style 和 Theme 的联系和区别,以及应用。
定义
style 是一组属性的集合,这些属性用于指定 View 或 window 的外观和样式。
theme 是 style,用于 Activity 或 application,而非单个 View;当使用theme 时,整个 Activity 或 application 内的 View 都会应用该 theme 的 style。
共同点
Style 和 Theme的内容的形式是一样的,都包含如下内容:
- 写在 xml 文件中;
- 根节点是 <resource>标签;
- <style> 标签及其唯一的 name 属性;
- <item> 标签;
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont">
<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>
区别
Style 和 Theme 的不同,在于应用对象:
- style 用于 View 或 Window;
- Theme 用于 Activity 或 Application;
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
<application android:theme="@style/CustomTheme">
<activity android:theme="@android:style/Theme.Dialog">
继承
如果是继承自己的 Style,直接在 name 属性中用 . 体现就可以了:
<style name="CodeFont.Red">
<item name="android:textColor">#FF0000</item>
</style>
和
<style name="CodeFont.Red.Big">
<item name="android:textSize">30sp</item>
</style>
引用方式分别是 @style/CodeFont.Red
和 @style/CodeFont.Red.Big
如果是继承系统提供的 Style,则需要在 <style> 标签中使用 parent 属性:
<style name="GreenText" parent="@android:style/TextAppearance">
<item name="android:textColor">#00FF00</item>
</style>
应用
设计和内容分离
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
主题
<application android:theme="@style/CustomTheme">
<activity android:theme="@android:style/Theme.Dialog">
自定义控件
用于自定义控件的自定义属性。
引用方式
- ?attr/ ,用于实现多用样式,见下章;
- @style/
- @android:style/
- <application android:theme=”@style/CustomTheme”>
- <activity android:theme=”@android:style/Theme.Dialog”>
系统内置一些样式,比如对话框形式的 Activity:
<activity android:theme="@android:style/Theme.Dialog">
比如背景透明的 Activity:
<activity android:theme="@android:style/Theme.Translucent">
设置多样式
假如某个布局有两种样式如下:
样式1
样式2
如上图,两种样式的不同体现在三处:
- 左侧文本的颜色,对应属性是 android:textColor;
- 右侧文本的背景,对应属性是 android:background;
- SwitchCompat 开关,对应属性是 colorControlActivated;
显然这三个属性的值不能写死,前两个要写成变量的形式 ,即写成 ?attr/xxxx:
<RelativeLayout
<TextView
android:text="取消"
android:textColor="?attr/cancelTextColor" />
<TextView
android:text="发布" />
<TextView
android:background="?attr/submitBtnBgColor"
android:text="发布" />
<android.support.v7.widget.SwitchCompat />
</RelativeLayout>
在 attrs.xml 里面定义 cancelTextColor 和 submitBtnBgColor 这两个变量:
<resources>
<attr name="cancelTextColor" format="reference" />
<attr name="submitBtnBgColor" format="reference" />
</resources>
然后在 styles.xml 里面给上述自定义属性写两套值,每一套即是一个 Style:
<style name="OrangeTheme">
<item name="cancelTextColor">@color/orange</item>
<item name="submitBtnBgColor">@drawable/orange_btn_bg</item>
</style>
<style name="BlueTheme">
<item name="cancelTextColor">@color/blue</item>
<item name="submitBtnBgColor">@drawable/blue_btn_bg_mt</item>
</style>
对于 SwitchCompat,跟前两个定义属性值略有不同,直接在 style 里面写两套颜色值即可:
<style name="OrangeTheme">
<item name="colorControlActivated">@color/orange</item>
</style>
<style name="BlueTheme">
<item name="colorControlActivated">@color/blue</item>
</style>
综上,在 styles.xml 里面给上述自定义属性写两套值,每一套即是一个 Style:
<style name="OrangeTheme">
<item name="cancelTextColor">@color/orange</item>
<item name="submitBtnBgColor">@drawable/orange_btn_bg</item>
<item name="colorControlActivated">@color/orange</item>
</style>
<style name="BlueTheme">
<item name="cancelTextColor">@color/blue</item>
<item name="submitBtnBgColor">@drawable/blue_btn_bg</item>
<item name="colorControlActivated">@color/blue</item>
</style>
最后在 Activity 里面设置具体使用哪一套值:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.TangramDpTheme);
setContentView(R.layout.main_layout);
}
注意,上述方法只使用静态设置,具体使用哪种样式需要在 Activity#onCreate() 方法里面写死,app 运行起来之后无法像皮肤一样动态改变。