樣式和主題(Styles and Themes)
一個樣式(Style)是一個包含了指定樣子和格式的作用于視圖控件(View)或者窗體(Window)屬性集合。一個style可以指定很多屬性砾脑,比如 高度聚假,填充待牵,字體顏色,字體尺寸评雌,背景色等譬淳。一個Style在xml資源文件中定義,并且和在xml中指定的布局區(qū)分開來祠斧。
在Android里的樣式和Web設(shè)計(jì)中的CSS共享一個相似的原理闻察,它們允許你分離設(shè)計(jì)(Design)和內(nèi)容(Content).
舉個例子,通過使用一個style,你可以讓你的布局xml像下面這樣:
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#00FF00"
android:typeface="monospace"
android:text="@string/hello" />
并且辕漂,可以變成下面這樣:
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
所有關(guān)聯(lián)到style的屬性已經(jīng)在布局xml中被刪除了呢灶,并且放在一個叫做“CodeFont”style中定義了。它通過一個style屬性被應(yīng)用上钉嘹。在下面的章節(jié)鸯乃,你將會看到如何定義style。
一個主題(Theme)也是一個style,它被應(yīng)用在所有的Activity或者application上跋涣,而不是個別的視圖控件(View)(像上面的示例一樣)缨睡。當(dāng)一個style被當(dāng)做一個theme來應(yīng)用,每一個activity或者application中的視圖控件將應(yīng)用每一個它支持的樣式屬性陈辱。比如奖年,你可以在activity上使用相同的CodeFont樣式作為一個theme,這時Activity里的所有內(nèi)部字體將會變成CodeFont樣式的字體樣式變成綠色的等寬字體沛贪。
定義一個樣式Style
為了創(chuàng)建一些樣式陋守,你可以保存在你的工程下的 res/Values/ 文件夾下的一個XML文件中。XML文件的名字是隨意的鹏浅,但是必須擴(kuò)展名是 .xml 并且存放在 res/Values/ 文件夾下嗅义。
XML文件的根節(jié)點(diǎn)必須是<resources>
為你創(chuàng)建的每個樣式屏歹,添加一個<style>元素隐砸,并且需要一個name 屬性,它標(biāo)識唯一性而且是必需的屬性蝙眶。再為你的樣式屬性都添加進(jìn)去季希,通過添加<item>元素來做,使用一個在樣式屬性里聲明的name屬性和一個value屬性幽纷,這兩個都是必需的式塌。<item>的value屬性可以是一個關(guān)鍵字字符串,一個16進(jìn)制的顏色描述友浸,一個其他資源類型的引用峰尝,或者在其他樣式屬性中依賴的value。下面是一個簡單的示例樣式文件內(nèi)容:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont" parent="@android:style/TextAppearance.Medium">
<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>
每一個<resources>元素的子節(jié)點(diǎn)在編譯時都被轉(zhuǎn)換成一個程序資源對象收恢。它可以通過<style>元素的name屬性的值(value)來被引用引用武学。這個示例樣式可以在XML布局中被引用,比如“@style/CodeFont”(像上面介紹的示例一樣)伦意。
在<style>元素中的parent屬性是可選的并且指向一個其他樣式中的資源ID火窒,它可以從這個樣式中繼承一些屬性。合適的話驮肉,你可以重寫(override)繼承到的屬性熏矿。
記住,一個你想在activity或者application中使用的樣式都被在XML文件中定義,并且所有的視圖控件具有相同的樣式票编。一個樣式褪储,比如上面定義的那個,可以被作為一style應(yīng)用的單一的視圖控件上或者被作為一個theme應(yīng)用在全部的activity或者application上栏妖。如何應(yīng)用的單一的視圖或者作為應(yīng)用的主題乱豆,我們稍后討論。
繼承
在<style>中的parent屬性讓你可以指定一個你可以繼承其屬性的樣式吊趾。你可以使用這個從一個已經(jīng)存在的樣式中繼承屬性宛裕,并且定義一些獨(dú)有的你需要改變或者添加的屬性。你可以繼承那些來自你已經(jīng)自行創(chuàng)建的樣式或者或者繼承自在平臺里構(gòu)建好的樣式(See Using Platform Styles and Themes论泛,下面揩尸,獲得關(guān)于繼承安卓平臺樣式的更多信息)。比如屁奏,你可以繼承安卓平臺默認(rèn)的字體樣式并且修改它岩榆,比如:
<style name="GreenText" parent="@android:style/TextAppearance">
<item name="android:textColor">#00FF00</item>
</style>
如果你想要繼承你自己創(chuàng)建的樣式,你不需要一定適用parent屬性坟瓢。作為替代勇边,可以為一個你想繼承的樣式的名字構(gòu)建前綴而作為你的新的樣式的名稱,中間用“點(diǎn)”隔開折联。比如粒褒,為了創(chuàng)建一個樣式,比如繼承自上面的CodeFont樣式诚镰,但是讓顏色變成紅色奕坟,你可以這樣寫你的新樣式:
<style name="CodeFont.Red">
<item name="android:textColor">#FF0000</item>
</style>
注意<style>標(biāo)簽沒有parent屬性,但是清笨,因?yàn)閚ame屬性是以CodeFont(這是個你已經(jīng)定義好的樣式)這個樣式名開始的月杉,這個樣式從哪個樣式里繼承了所有的樣式屬性。這個樣式這里覆蓋里android:textColor屬性抠艾,將文本改成了紅色苛萎。你可以引用這個新的樣式比如@style/CodeFont.Red。
你可以繼續(xù)這樣繼承很多次检号,使用“點(diǎn)”鏈接這些名稱腌歉,比如,你可以擴(kuò)展CodeFont.Red 變大一些谨敛,像下面這樣:
<style name="CodeFont.Red.Big">
<item name="android:textSize">30sp</item>
</style>
這里從CodeFont和CodeFont.Red繼承了究履,又添加了 android:textSize 屬性
注意:這樣的通過鏈接名稱的方式來繼承的方法,僅僅能用于你自己定義的資源文件中的樣式脸狸。你不能用于繼承安卓內(nèi)置的樣式最仑。要想引用內(nèi)置的樣式藐俺,比如TextAppearance,,你必須使用parent屬性泥彤。
樣式屬性
現(xiàn)在欲芹,你明白了如何定義一個樣式,你需要去學(xué)會 在<item>元素下什么類型被定義的樣式屬性是可用的吟吝。你可能已經(jīng)熟悉了很多已經(jīng)有的菱父,比如layout_width 和 textColor. 當(dāng)然,還有很多的樣式屬性你可以使用剑逃。
尋找可以應(yīng)用在指定視圖控件上的屬性的最好的地方是 相應(yīng)的類引用浙宜,它列出了所有支持的XML屬性。比如所有在表格 TextView XML attributes 中列出的屬性蛹磺,都可以應(yīng)用在一個樣式的定義中作用在TextView元素上(或者它的子類)粟瞬。在 引用 中被列出的一個屬性叫做android:inputType的,這樣你可以再<EditText>元素中應(yīng)用這個屬性萤捆,像下面這樣:
<EditText
android:inputType="number"
... />
你可以為EditText 元素創(chuàng)建一個樣式裙品,包含這個屬性,來代替上面:
<style name="Numbers">
<item name="android:inputType">number</item>
...
</style>
這樣你的布局用的XML能夠這樣實(shí)現(xiàn)樣式:
<EditText
style="@style/Numbers"
... />
這個簡單的示例看起來多做了一些工作俗或,不過當(dāng)你添加更多的樣式屬性并且把在多處可重用樣式的能力作為參考因素的話市怎,你的付出將是值得的。
獲得所有可用樣式的屬性的引用(reference)辛慰,請參閱 R.attr 引用区匠。記住,所有的視圖控件對象不接受所有相同的屬性昆雀,這樣你可以平常的引用圖為視圖控件類指定支持的樣式屬性辱志。然而蝠筑,如果你為某個視圖控件應(yīng)用了一個樣式狞膘,這個樣式包含的屬性中不是都被支持的,視圖控件將會應(yīng)用那些屬性中的可被支持的并且簡單的忽略其他的什乙。
一些樣式屬性挽封,不被支持在視圖控件里使用,僅僅能作為主題使用臣镣。那些樣式屬性應(yīng)用在所有的窗體上辅愿,不能用在任何視圖控件上。比如有些樣式屬性可以隱藏應(yīng)用程序的標(biāo)題忆某,隱藏狀態(tài)條点待,或者更改窗體的背景。那些類型的樣式屬性不屬于任何視圖控件對象弃舒。要發(fā)現(xiàn)更多 僅僅作用于theme主題 的屬性癞埠,查看R.attr 引用中的以windows開始的屬性状原。比如,windowNoTitle 和 windowBackground 屬性只能在應(yīng)用于activity和application時發(fā)生作用苗踪。參閱下一章節(jié)可以獲得更多“在theme中應(yīng)用樣式”的內(nèi)容颠区。
注意:在<item>元素中,不要忘記寫屬性名稱的前綴 android: 通铲,這是一個命名空間毕莱,比如:<item name="android:inputType">.
在UI上應(yīng)用樣式和主題
有兩種方式設(shè)置一個樣式:
- 為單個視圖控件指定樣式,在XML布局文件中的視圖元素上添加style屬性颅夺。
- 為整個activity或者application指定樣式朋截,在manifest.xml中的<activity>或者<application>節(jié)點(diǎn)元素中添加 android:theme 屬性。
當(dāng)你為布局里的單個控件中應(yīng)用一個樣式吧黄,你的樣式中定義的屬性都會應(yīng)用在這個視圖組件中质和。如果你的樣式應(yīng)用在一個ViewGroup中,它的所有子控件元素將不能繼承這些樣式的屬性稚字,只有你直接指定的那個視圖元素可以應(yīng)用這些屬性饲宿。不過,你仍然可以通過主題的方式為你的應(yīng)用下的所有視圖元素應(yīng)用樣式胆描。
要想應(yīng)用一個主題瘫想,你必須在manifest.xml中為activity或者aplication上應(yīng)用樣式。當(dāng)你這么做昌讲,每一個Activity或者aplication里的視圖元素都將應(yīng)用這些樣式中它支持的屬性国夜。比如,如果應(yīng)用上面提到的CodeFont樣式在一個Activity上短绸,這是所有的支持文本樣式屬性的視圖元素將應(yīng)用它們车吹。一些不支持這些屬性的視圖元素將忽略它們。如果一個視圖支持一部分屬性醋闭,那么它將只應(yīng)用這些屬性窄驹。
在視圖元素中應(yīng)用樣式
下面演示如何在XML布局中設(shè)置一個樣式:
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
現(xiàn)在 TextView將具有樣式,像CodeFont定義的屬性描述的一樣证逻。你可以參考上面的示例乐埠。
注意:樣式style 不需要使用android: 命名空間前綴。
在activity或者application中應(yīng)用樣式
要想再你的所有activity或者application上使用樣式囚企,打開 AndroidManifest.xml 并且修改<application>標(biāo)簽丈咐,讓它包含 android:theme 屬性并指定一個樣式名稱,比如:
<application android:theme="@style/CustomTheme">
如果你想為你的應(yīng)用中的某個activity使用樣式龙宏,那么添加 android:theme 到你的<activity>標(biāo)簽中棵逊。
安卓提供了一些內(nèi)置資源,你可以使用這些預(yù)先定義好的樣式银酗,而不用自己再重新寫了辆影。比如掩浙,你可以使用Dialog主題讓你的Activity 表現(xiàn)的像一個 對話框:
<activity android:theme="@android:style/Theme.Dialog">
或者你想讓你的背景透明,使用 透明主題:
<activity android:theme="@android:style/Theme.Translucent">
如果你喜歡主題秸歧,但是想開足馬力使用它厨姚,那么你可以添加它到你的自定義主題中的parent屬性上繼承它。比如键菱,你可以修改 傳統(tǒng)的 light theme 主題并使用你的自己的顏色谬墙,像下面這樣:
<color name="custom_theme_color">#b0b0ff</color>
<style name="CustomTheme" parent="android:Theme.Light">
<item name="android:windowBackground">@color/custom_theme_color</item>
<item name="android:colorBackground">@color/custom_theme_color</item>
</style>
注意上面用到的顏色在其他資源中被提供,這里经备,因?yàn)閍ndroid:windowBackground 屬性僅僅支持其他資源的引用拭抬,不像 android:colorBackground屬性可以指定一個顏色描述文本。
現(xiàn)在侵蒙,在你的Mnaifest文件中造虎,可以使用 CustomTheme 代替 Theme.Light:
<activity android:theme="@style/CustomTheme">
選擇一個平臺支持的樣式作為基礎(chǔ)
安卓較新的版本為應(yīng)用提供了額外的可用的樣式,同時你可能想要使用它們在那些平臺上運(yùn)行纷闺,并且仍然和老版本保持兼容算凿。你可以通過自定樣式做到,使用“資源選擇器"來切換不同的父主題犁功,基于平臺版本氓轰。
比如,下面是一個自定義樣式的聲明浸卦,這個樣式是個簡單的標(biāo)準(zhǔn)平臺默認(rèn)的 light theme主題署鸡。它可能被放置在res/valeus文件夾下的 XML文件中(經(jīng)典的是在 res/values/styles.xml)。
<style name="LightThemeSelector" parent="android:Theme.Light">
...
</style>
當(dāng)應(yīng)用跑在Android 3.0(API級別11)或者更高以上時限嫌,可以讓這個樣式使用較為新一些的holo風(fēng)格主題靴庆,你可以放置一個可供選擇的聲明樣式防止在res/values-v11這個文件夾下的XML文件中,但是讓這個樣式繼承自 holo風(fēng)格的主題:
<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
...
</style>
現(xiàn)在可以像任意其他那樣來使用這個主題怒医,并且當(dāng)跑在安卓3.0以上時炉抒,你的應(yīng)用程序會自動切換到holo風(fēng)格的主題。
在 R.styleable.Theme. 里裆熙,可以找到一個標(biāo)準(zhǔn)的屬性列表供你使用端礼。
關(guān)于更多的信息禽笑,像比如主題和布局入录,基于平臺版本或者設(shè)備配置等切換資源文件選擇,你可以閱讀 Providing Resources 佳镜。
使用平臺樣式和主題
安卓平臺提供了很多樣式和主題僚稿,供你在應(yīng)用程序中使用。在 R.style 類里你可以找到可以用的引用蟀伸。為了使用這里列出的樣式蚀同,你可以使用”點(diǎn)“替換所有的下劃線分割的 樣式名稱缅刽,比如,你可以通過”"@android:style/Theme.NoTitleBar".來使用 Theme_NoTitleBar 樣式蠢络。
R.style 引用衰猛,然而,不是和好的文件記錄刹孔,并且不能全面的描述樣式啡省,那么查看那些樣式和主題的實(shí)際的資源代碼可以給你更好一些關(guān)于”各個被提供樣式屬性“的的理解。獲得更多關(guān)于樣式和主題的引用髓霞,你可以看下面的源代碼:
Android Styles (styles.xml)
Android Themes (themes.xml)
那些文件將通過實(shí)例幫助你學(xué)習(xí)卦睹。比如,在安卓的主題源代碼中方库,你將找到一個聲明 <style name="Theme.Dialog">.在這些定義里结序,你將會看到所有的常常用到的 ”被用于安卓框架的樣式對話框的屬性“
更多關(guān)于 樣式和主題 在XML中的語法的信息,請參閱 Style Resource 文檔纵潦。
對于 一個可用的樣式屬性的引用徐鹤,你可以它使用定義一個樣式或者主題(比如"windowBackground" 或者 "textAppearance),在你創(chuàng)建一個樣式時你可以閱讀 R.attr 或者各自的視圖類邀层。
本文翻譯自:https://developer.android.com/guide/topics/ui/themes.html