Android編程權(quán)威指南(第二版)學(xué)習(xí)筆記(二十)—— 第20章 樣式與主題

本章主要講了如何使用樣式與主題(style and theme),使應(yīng)用界面統(tǒng)一化標(biāo)準(zhǔn)化。

GitHub 地址:
完成第20章

1. 樣式(Style)

1.1 樣式的定義

樣式是一組能應(yīng)用于視圖組件的屬性,用于復(fù)用相同的 UI 特性

例如我們?cè)?res/values/style.xml 中定義一個(gè)樣式:

<style name="BeatBoxButton">
    <item name="android:background">@color/dark_blue</item>
    <!--其中的 color 資源在 colors.xml 中定義-->
</style>

那么使用這個(gè)樣式的組件就會(huì)自動(dòng)套用這個(gè)屬性:

<Button
    ……
    style="@style/BeatBoxButton"
    <!--這樣就能自動(dòng)套用這個(gè)背景的顏色-->
    ……/>

1.2 樣式的繼承

樣式的繼承可以在原有樣式的基礎(chǔ)上添加和覆蓋屬性

  • 繼承方式一:通過命名表示樣式繼承關(guān)系

    <!--用點(diǎn)連接表示繼承關(guān)系败京,只能在包內(nèi)使用-->
    <style name="BeatBoxButton.Strong">
        <item name="android:textStyle">bold</item>
    </style>
    
  • 繼承方式二:用指定父樣式的方法繼承

    <!--用 parent 屬性表示繼承關(guān)系,可以跨庫(kù)使用-->
    <style name="StrongBeatBoxButton" 
            parent="@style/BeatBoxButton">
        <item name="android:textStyle">bold</item>
    </style>
    

2. 主題(Theme)

樣式能讓一些屬性復(fù)用,看上去節(jié)省了許多工作揍庄,在 styles.xml 公共文件中,可以為所有組件定義一套樣式屬性共用东抹。然而蚂子,如果組件多了,需要逐個(gè)為所有組件添加它們要用到的樣式缭黔,工作量是很大的食茎。

這個(gè)時(shí)候主題就可以派上用場(chǎng)了×蠼鳎可以把主題看作樣式的進(jìn)化加強(qiáng)版别渔,同樣是定義一套公共主題屬性,樣式屬性需要逐個(gè)添加惧互,而主題屬性則會(huì)自動(dòng)應(yīng)用于整個(gè)應(yīng)用哎媚。主題屬性能引用顏色這樣的外部資源,也能引用其他樣式喊儡。使用主題拨与,可以簡(jiǎn)單地說:“所有按鈕都使用這個(gè)樣式」芟”再也不用找到每個(gè)按鈕截珍,告訴它們要用哪個(gè)主題了。

2.1 主題屬性的更改

主題作用于某個(gè) activity 或者整個(gè)應(yīng)用箩朴,這和主題在 manifest 文件中的聲明位置有關(guān)岗喉,如果在 <application> 標(biāo)簽中聲明,則是作用于整個(gè)應(yīng)用炸庞,在<activity>標(biāo)簽中聲明钱床,則是作用于單個(gè) activity。

在 manifest 文件中我們看到整個(gè)應(yīng)用的主題是android:theme="@style/AppTheme"埠居,按住 Command(Windows 下是 Ctrl)查牌,點(diǎn)擊 AppTheme 就可以進(jìn)入其聲明的位置,可以看到以下代碼:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
</style>

AppCompat 庫(kù)自帶三大主題:

  • Theme.AppCompat——深色主題
  • Theme.AppCompat.Light——淺色主題
  • Theme.AppCompat.Light.DarkActionBar——帶深色工具欄的淺色主題
    我們把 AppTheme 的父主題修改為 Theme.AppCompat滥壕,以便于修改屬性纸颜。

2.1.1 修改主題顏色

在空空的主題 style 標(biāo)簽中加入幾個(gè)屬性,如下:

<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 屬性主要用來(lái)設(shè)置工具欄背景色绎橘。由于應(yīng)用名稱是顯示在工具欄上的胁孙,colorPrimary 也可以稱為應(yīng)用品牌色
  • colorPrimaryDark 用于屏幕頂部的狀態(tài)欄。從名字可以看出,它是深色版 colorPrimary涮较。 注意稠鼻,只有 Lollipop 以后的系統(tǒng)支持狀態(tài)欄主題色。對(duì)于之前的系統(tǒng)狂票,無(wú)論指定什么主題色候齿,狀態(tài)欄都是不變的黑底色。
  • 最后闺属,將 colorAccent 設(shè)置為灰色的慌盯。這個(gè)主題色應(yīng)該和 colorPrimary 形成反差效果,主要用于給 EditText 這樣的組件著色屋剑。

2.2 主題的抽絲剝繭

完成了主題配色润匙,我們繼續(xù)來(lái)點(diǎn)深入的诗眨,比如可以看看可以覆蓋的主題屬性都有哪些唉匾。在研究諸如有哪些主題屬性可用,哪些能覆蓋匠楚,甚至是有某些屬性究竟有什么作用等這樣的問題時(shí)巍膘,幾乎沒有官方參考文檔可以參考,所以要逐級(jí)往上查看芋簿。

例如峡懈,我想找到設(shè)置頁(yè)面背景顏色的屬性(隨著時(shí)間的推移,主題繼承關(guān)系和層次可能有變与斤,但下面介紹的方法不會(huì)變肪康。 想要知道該覆蓋哪個(gè)屬性,就沿著繼承樹找吧!):

第一層

也就是 AppTheme 主題撩穿,它原本是個(gè) Android Studio 自動(dòng)生成的空的主題磷支。

為什么要生成一個(gè)空主題,而不在 manifest 中直接使用Theme.AppCompat.Light.DarkActionBar呢食寡?這就是設(shè)計(jì)模式的事情了雾狈,對(duì)于應(yīng)用本身來(lái)說,使用的主題不管父主題是誰(shuí)抵皱,引用的都是 AppTheme 這個(gè)主題善榛,相當(dāng)于定義主題的時(shí)候留出了一個(gè) AppTheme 的接口。對(duì)于協(xié)作開發(fā)來(lái)說呻畸,你不用管我內(nèi)部如何實(shí)現(xiàn)也不用操心該怎么引用移盆,只要使用 AppTheme 就夠了。

我們繼續(xù)往上找伤为。

第二層

進(jìn)入 Theme.AppCompat咒循,可以看到其也是一個(gè)空主題:

<style name="Theme.AppCompat" parent="Base.Theme.AppCompat"/>

要進(jìn)入上一層時(shí),可以看到有好幾個(gè)候選的父主題,這里我們選擇 values-v21 目錄下的父主題

第三層

這一層仍然是空主題

<style name="Base.Theme.AppCompat" parent="Base.V21.Theme.AppCompat"/>

那就再往上走

第四層

終于出現(xiàn)了很多屬性

<style name="Base.V21.Theme.AppCompat" parent="Base.V7.Theme.AppCompat">
    ……
</style>

但是沒有我們想要的設(shè)置背景的屬性剑鞍,所以要繼續(xù)往上

第五層

也定義了很多屬性昨凡,但是也沒有需要的

<style name="Base.V7.Theme.AppCompat" parent="Platform.AppCompat">
    ……
</style>

繼續(xù)往上,這里 Platform.AppCompat也有多個(gè)版本蚁署,我們選擇 values-v11 下的父主題

第六層

空主題便脊,繼續(xù)往上

<style name="Platform.AppCompat" parent="Platform.V11.AppCompat"/>

第七層

終于看到了我們想要的屬性:

<!--可以看到這個(gè)主題的 parent 是帶有 android 命名空間的,表示其來(lái)源于 Android 系統(tǒng)-->
<style name="Platform.V11.AppCompat" parent="android:Theme.Holo">
        ……
        <!-- Window colors -->
        ……
        <item name="android:colorBackground">@color/background_material_dark</item>
        ……

</style>

所以光戈,最后我們可以在 AppTheme 中覆蓋這個(gè)屬性哪痰,設(shè)置背景顏色:

<item name="colorBackground">@color/soothing_blue</item>

2.3 修改按鈕顏色

同樣的饺律,我們?cè)偻险也阶觯茉?android:Theme.Holo 中找到 buttonStyle 屬性:

<item name="buttonStyle">@style/Widget.Holo.Button</item>

這樣,我們的 BeatBoxButton 可以繼承 Widget.Holo.Button 這個(gè)樣式功炮,然后在 AppTheme 中使用 buttonStyle 屬性筷弦。

3. 引用主題屬性

在主題中定義好屬性后肋演,可以在 XML 或代碼中直接使用它們。
在 XML 中引用具體值時(shí)(如顏色值)烂琴,我們使用@符號(hào)爹殊。比如 @color/gray 指向某個(gè)特定資源。
在主題中引用資源時(shí)奸绷,我們使用?符號(hào)梗夸。
比如:

<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. 挑戰(zhàn)練習(xí)

新建 values-v21 下的 styles.xml 文件,繼承自 Widget.Material.Button 即可


GitHub Page: kniost.github.io
簡(jiǎn)書:http://www.reibang.com/u/723da691aa42

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末号醉,一起剝皮案震驚了整個(gè)濱河市反症,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌畔派,老刑警劉巖铅碍,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異父虑,居然都是意外死亡该酗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門士嚎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)呜魄,“玉大人,你說我怎么就攤上這事莱衩【粜幔” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵笨蚁,是天一觀的道長(zhǎng)睹晒。 經(jīng)常有香客問我趟庄,道長(zhǎng),這世上最難降的妖魔是什么伪很? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任戚啥,我火速辦了婚禮,結(jié)果婚禮上锉试,老公的妹妹穿的比我還像新娘猫十。我一直安慰自己,他們只是感情好呆盖,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布拖云。 她就那樣靜靜地躺著,像睡著了一般应又。 火紅的嫁衣襯著肌膚如雪宙项。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天株扛,我揣著相機(jī)與錄音尤筐,去河邊找鬼。 笑死席里,一個(gè)胖子當(dāng)著我的面吹牛叔磷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播奖磁,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼繁疤!你這毒婦竟也來(lái)了咖为?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤稠腊,失蹤者是張志新(化名)和其女友劉穎躁染,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體架忌,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吞彤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叹放。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饰恕。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖井仰,靈堂內(nèi)的尸體忽然破棺而出埋嵌,到底是詐尸還是另有隱情,我是刑警寧澤俱恶,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布雹嗦,位于F島的核電站范舀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏了罪。R本人自食惡果不足惜锭环,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泊藕。 院中可真熱鬧田藐,春花似錦、人聲如沸吱七。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)踊餐。三九已至景醇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吝岭,已是汗流浹背三痰。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窜管,地道東北人散劫。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像幕帆,于是被迫代替她去往敵國(guó)和親获搏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容