1.落筆緣由
本文主要是對Android主題和樣式的研究樟氢,本文主要是以摘抄官方文檔(地址在參考文章中給出)的內(nèi)容疯特,在每段結尾進行總結的形式來了解Android主題和樣式堵第。
2.什么是樣式蜘腌,主題
樣式是指為 View 或窗口指定外觀和格式的屬性集合辰如。樣式可以指定高度赞咙、填充责循、字體顏色、字號攀操、背景色等許多屬性院仿。 樣式是在與指定布局的 XML 不同的 XML 資源中進行定義。
Android 中的樣式與網(wǎng)頁設計中層疊樣式表的原理類似 — 您可以通過它將設計與內(nèi)容分離速和。
例如歹垫,通過使用樣式,您可以將以下布局 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" />
布局 XML 中所有與樣式有關的屬性都已移除颠放,并置于一個名為 CodeFont 的樣式定義內(nèi)排惨,然后通過 style 屬性加以應用。 您會在下文中看到對該樣式的定義碰凶。
主題是指對整個 Activity 或應用而不是對單個 View(如上例所示)應用的樣式暮芭。 以主題形式應用樣式時,Activity 或應用中的每個視圖都將應用其支持的每個樣式屬性痒留。 例如谴麦,您可以 Activity 主題形式應用同一 CodeFont 樣式,之后該 Activity 內(nèi)的所有文本都將具有綠色固定寬度字體伸头。
簡單來說樣式是相對于View等控件來說的匾效,相當于web中的css恤磷。而主題是相對于Activity來說的面哼,主題不單止是對Activity的生命周期(例如定義了ActivityB透明背景, 當Activity A啟動Activity B野宜, A不透明虎敦,B透明其徙,那么 A的onStop不會被調(diào)用,只會調(diào)用onPause喷户。相當于啟動了一個dialog唾那。)和轉(zhuǎn)場動畫有影響,還有可能影響到Activity界面里的View控件,dialog樣式和popupWindow褪尝。
3.如何定義樣式
要創(chuàng)建一組樣式闹获,請在您的項目的 res/values/ 目錄中保存一個 XML 文件。 可任意指定該 XML 文件的名稱河哑,但它必須使用 .xml 擴展名避诽,并且必須保存在 res/values/ 文件夾內(nèi)。
該 XML 文件的根節(jié)點必須是 <resources>灾馒。
對于您想創(chuàng)建的每個樣式茎用,向該文件添加一個 <style> 元素,該元素帶有對樣式進行唯一標識的 name 屬性(該屬性為必需屬性)睬罗。然后為該樣式的每個屬性添加一個 <item> 元素轨功,該元素帶有聲明樣式屬性以及屬性值的 name(該屬性為必需屬性)。 根據(jù)樣式屬性容达,<item> 的值可以是關鍵字字符串古涧、十六進制顏色值、對另一資源類型的引用或其他值花盐。以下是一個包含單個樣式的示例文件:
<?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> 元素的每個子項都會在編譯時轉(zhuǎn)換成一個應用資源對象羡滑,該對象可由 <style> 元素的 name 屬性中的值引用。 可從 XML 布局以 @style/CodeFont 形式引用該示例樣式(如上文引言中所示)算芯。
<style> 元素中的 parent 屬性是可選屬性柒昏,它指定應作為此樣式所繼承屬性來源的另一樣式的資源 ID。 如果愿意熙揍,您可在隨后替換這些繼承的樣式屬性职祷。
切記,在 XML 中定義您想用作 Activity 或應用主題的樣式與定義視圖樣式的方法完全相同。 諸如上文所定義的樣式可作為單個視圖的樣式加以應用有梆,也可作為整個 Activity 或應用的主題加以應用是尖。 后文將闡述如何為單個視圖應用樣式或如何以應用主題形式應用樣式。
簡單來說:
(1) 在res/value目錄下創(chuàng)建一個xml文件泥耀,該文件名可以隨意命名(當然了饺汹,前提還是要遵守命名規(guī)則)。
(2) 在 XML 中定義您想用作 Activity 或應用主題的樣式與定義視圖樣式的方法完全相同痰催。
1)繼承
您可以通過 <style> 元素中的 parent 屬性指定應作為您的樣式所繼承屬性來源的樣式兜辞。您可以利用它來繼承現(xiàn)有樣式的屬性,然后只定義您想要更改或添加的屬性夸溶。 您可以從自行創(chuàng)建的樣式或平臺內(nèi)建的樣式繼承屬性弦疮。 (如需了解有關從 Android 平臺定義的樣式繼承屬性的信息,請參閱下文的使用平臺樣式和主題蜘醋。) 例如,您可以繼承 Android 平臺的默認文本外觀咏尝,然后對其進行修改:
<style name="GreenText" parent="@android:style/TextAppearance">
<item name="android:textColor">#00FF00</item>
</style>
如果您想從自行定義的樣式繼承屬性压语,則不必使用 parent 屬性, 而是只需將您想繼承的樣式的名稱以前綴形式添加到新樣式的名稱之中编检,并以句點進行分隔胎食。 例如,要創(chuàng)建一個繼承上文定義的 CodeFont 樣式的新樣式允懂,但將顏色設置為紅色厕怜,您可以按如下方式創(chuàng)建這個新樣式:
<style name="CodeFont.Red">
<item name="android:textColor">#FF0000</item>
</style>
請注意,<style> 標記中沒有 parent 屬性蕾总,但由于 name 屬性以 CodeFont 樣式名稱(這是您創(chuàng)建的一個樣式)開頭粥航,因此這個樣式會繼承該樣式的所有樣式屬性。 這個樣式隨后會替換 android:textColor 屬性生百,將文本設置為紅色递雀。 您可以 @style/CodeFont.Red 形式引用這個新樣式。
您可以通過使用句點鏈接名稱繼續(xù)進行這樣的繼承蚀浆,次數(shù)不限缀程。 例如,您可以通過以下代碼將 CodeFont.Red 擴大:
<style name="CodeFont.Red.Big">
<item name="android:textSize">30sp</item>
</style>
這段代碼同時從 CodeFont 和 CodeFont.Red 樣式繼承市俊,然后添加 android:textSize 屬性杨凑。
簡單來說:
(1)自定義樣式和系統(tǒng)樣式的繼承方式是不一樣的,自定義樣式可以通過點“.”來實現(xiàn)繼承摆昧,而系統(tǒng)樣式必須通過parent 屬性來繼承撩满。
2)樣式屬性
相應的類引用最便于查找適用于特定 View 的屬性,其中列出了所有支持的 XML 屬性。 例如鹦牛,TextView XML 屬性表中所列的所有屬性都可在 TextView 元素(或其其中一個子類)的樣式定義中使用搞糕。 該引用中列出的其中一個屬性是 android:inputType,因此曼追,如果您正常情況下會在 <EditText> 元素中放置 android:inputType 屬性窍仰,如下所示:
<EditText
android:inputType="number"
... />
您就可以改為給包括該屬性的 EditText 元素創(chuàng)建一個樣式:
<style name="Numbers">
<item name="android:inputType">number</item>
...
</style>
這樣您的布局 XML 現(xiàn)在便可實現(xiàn)這個樣式:
<EditText
style="@style/Numbers"
... />
這個簡單示例可能顯得工作量更大,但如果您添加更多樣式屬性并將能夠在各種地方重復使用樣式這一因素考慮在內(nèi)礼殊,就會發(fā)現(xiàn)回報可能很豐厚驹吮。
如需查看所有可用樣式屬性的參考資料,請參閱 R.attr 參考資料晶伦。 切記碟狞,所有 View 對象仍然不接受樣式屬性,因此正常情況下您應該引用所支持樣式屬性的具體 View 類婚陪。 不過族沃,如果您應用樣式的 View 不支持所有樣式屬性,該 View 將只應用那些受支持的屬性泌参,并直接忽略其他屬性脆淹。
不過,某些樣式屬性任何 View 元素都不提供支持沽一,只能以主題形式應用盖溺。 這些樣式屬性應用于整個窗口而非任何類型的 View。例如铣缠,主題的樣式屬性可以隱藏應用標題烘嘱、隱藏狀態(tài)欄或更改窗口的背景。 這些類型的樣式屬性不屬于任何 View 對象蝗蛙。要發(fā)現(xiàn)這些僅主題樣式屬性蝇庭,請在 R.attr 參考資料中查看有關以 window 開頭的屬性的內(nèi)容。 例如歼郭,windowNoTitle 和 windowBackground 是只有在樣式以主題形式應用于 Activity 或應用時才起作用的樣式屬性遗契。 請參閱下文有關以主題形式應用樣式的信息。
簡單來說:
(1) 并不是所有的樣式屬性都能被View使用的病曾,例如windowNoTitle等樣式屬性View是無法識別的牍蜂。所以對于View不支持的樣式屬性,View會忽略掉它們泰涂,只將那些View支持的樣式屬性應用到View上鲫竞。
(2) 如何判斷View支持哪些屬性,可以到View的api下逼蒙,查看它的xml屬性
如下圖
(3) R.attr里有所有的樣式屬性从绘。
(4) 在R.attr里,如果要查看僅主題樣式可使用的屬性,那么查看有關以 window 開頭的屬性的內(nèi)容僵井。
4. 如何使用自定義樣式和主題樣式
設置樣式的方法有兩種:
? 如果是對單個視圖應用樣式陕截,請為布局 XML 中的 View 元素添加 style 屬性。
? 或者批什,如果是對整個 Activity 或應用來應用樣式农曲,請為 Android 清單中的 <activity> 或 <application> 元素添加 android:theme 屬性。
當您對布局中的單個 View 應用樣式時驻债,該樣式定義的屬性只應用于該 View乳规。 如果對 ViewGroup 應用樣式,子 View元素將不會繼承樣式屬性 — 只有被您直接應用樣式的元素才會應用其屬性合呐。 不過暮的,您可以通過以主題形式應用樣式,使所應用的樣式作用于所有 View 元素淌实。
要以主題形式應用樣式定義冻辩,您必須在 Android 清單中將樣式應用于 Activity 或應用。 如果您這樣做拆祈,Activity 或應用內(nèi)的每個 View 都將應用其支持的每個屬性微猖。 例如,如果您對某個 Activity 應用前面示例中的 CodeFont 樣式缘屹,則所有支持這些文本樣式屬性的 View 元素也會應用這些屬性。 任何不支持這些屬性的 View 都會忽略這些屬性侠仇。 如果某個 View 僅支持部分屬性轻姿,將只應用這些屬性。
1)對視圖應用樣式
為 XML 布局中的視圖設置樣式的方法如下:
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
現(xiàn)在該 TextView 將按照名為 CodeFont 的樣式的定義設置樣式(請參閱上文定義樣式中的示例)逻炊。
2)對 Activity 或應用應用主題
要為您的應用的所有 Activity 設置主題互亮,請打開 AndroidManifest.xml 文件并編輯 <application> 標記,在其中加入帶樣式名稱的 android:theme 屬性余素。 例如:
<application android:theme="@style/CustomTheme">
如果您只想對應用中的一個 Activity 應用主題豹休,則改為給 <activity> 標記添加 android:theme 屬性。
正如 Android 提供了其他內(nèi)建資源一樣桨吊,有許多預定義主題可供您使用威根,可免于自行編寫。 例如视乐,您可以使用 Dialog 主題洛搀,為您的 Activity 賦予類似對話框的外觀:
<activity android:theme="@android:style/Theme.Dialog">
或者,如果您希望背景是透明的佑淀,則可使用 Translucent 主題:
<activity android:theme="@android:style/Theme.Translucent">
如果您喜歡某個主題留美,但想做些調(diào)整,只需將該主題添加為您的自定義主題的 parent。 例如谎砾,您可以像下面這樣對傳統(tǒng)明亮主題進行修改逢倍,使用您自己的顏色:
<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>
(請注意,此處顏色需要以單獨資源形式提供景图,因為 android:windowBackground 屬性僅支持對另一資源的引用较雕;不同于 android:colorBackground,無法為其提供顏色字面量症歇。)
現(xiàn)在郎笆,在 Android 清單內(nèi)使用 CustomTheme 替代 Theme.Light:
<activity android:theme="@style/CustomTheme">
3)根據(jù)平臺版本選擇主題
新版本的 Android 可為應用提供更多主題,您可能希望在這些平臺上運行時可以使用這些新增主題忘晤,同時仍可兼容舊版本宛蚓。 您可以通過自定義主題來實現(xiàn)這一目的,該主題根據(jù)平臺版本利用資源選擇在不同父主題之間切換设塔。
例如凄吏,以下這個聲明所對應的自定義主題就是標準的平臺默認明亮主題。 它位于 res/values 之下的一個 XML 文件(通常是 res/values/styles.xml)中:
<style name="LightThemeSelector" parent="android:Theme.Light">
...
</style>
為了讓該主題在應用運行在 Android 3.0(API 級別 11)或更高版本系統(tǒng)上時使用更新的全息主題闰蛔,您可以在 res/values-v11 下的 XML 文件中加入一個替代主題聲明痕钢,但將父主題設置為全息主題:
<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
...
</style>
現(xiàn)在像您使用任何其他主題那樣使用該主題,您的應用將在其運行于 Android 3.0 或更高版本的系統(tǒng)上時自動切換到全息主題序六。
R.styleable.Theme 提供了可在主題中使用的標準屬性的列表任连。
簡單來說:
(1) 對View使用樣式,只需要在使用View的xml布局文件里的該View標簽下使用style屬性例诀。
(2) 對于ViewGroup使用樣式随抠,是不會影響到ViewGroup里的其他View的樣式的,也就是說ViewGroup里的View是不會繼承ViewGroup的樣式的繁涂。
(3) 主題里定義的樣式是會應用到Activity 或應用內(nèi)的每個 View的拱她。
例如:
在value的style.xml定義了一個主題
在Activity里使用這個主題:
效果如下:
(4) 對于某些樣式屬性,至少使用對另一資源的引用
(5) 可以給不同Androdid版本定義不同的主題,例如默認主題是res/value下的style.xml文件里定義名為LightThemeSelector的主題扔罪,如果我想在Android3.0(API為11)的系統(tǒng)顯示不同的主題秉沼,可以在res目錄下創(chuàng)建一個名為value-v11的文件夾,然后在里面的style.xml文件也命名一個LightThemeSelector的主題矿酵,如何根據(jù)需求使用對于的屬性唬复。
(6) R.styleable.Theme 提供了可在主題中使用的標準屬性的列表。
4. 使用平臺樣式和主題
Android 平臺提供了龐大的樣式和主題集合全肮,供您在應用中使用盅抚。 您可以在 R.style 類中找到所有可用樣式的參考資料。 要使用此處所列樣式倔矾,請將樣式名稱中的所有下劃線替換為句點妄均。 例如柱锹,您可以使用 "@android:style/Theme.NoTitleBar" 應用 Theme_NoTitleBar 主題。
不過丰包,R.style 參考資料并不完備禁熏,未對樣式做全面說明,因此查看這些樣式和主題的實際源代碼可讓您更清楚地了解每個樣式提供的樣式屬性邑彪。如需查看更詳實的 Android 樣式和主題參考資料瞧毙,請參閱以下源代碼:
? Android 樣式 (styles.xml)
? Android 主題 (themes.xml)
這些文件有助于您通過示例進行學習。例如寄症,在 Android 主題源代碼中宙彪,您可以找到 <style name="Theme.Dialog">的聲明。 在該定義中有巧,您可以看到用來為 Android 框架使用的對話框設置樣式的所有屬性释漆。
如需了解有關 XML 中樣式和主題語法的詳細信息,請參閱樣式資源文檔篮迎。
如需查看您可用來定義樣式或主題的可用樣式屬性(例如“windowBackground”或“textAppearance”)的參考資料男图,請參閱 R.attr 或您創(chuàng)建的樣式所對應的 View 類。
這里沒什么好說的甜橱,這段告訴我們可以到哪去查看系統(tǒng)提供給我們的樣式和主題逊笆。其實也挺重要的,我們可以查看我們使用的主題岂傲,看看哪些屬性影響到我們的控件樣式难裆,然后就可以自定義我們的樣式覆蓋掉系統(tǒng)的樣式。
6. 參考文章
https://developer.android.com/guide/topics/ui/themes.html?hl=zh-cn