創(chuàng)建一個(gè) Android 工程,第一步,也是必不可少的一步,就是定制 Application 主題樣式。利用系統(tǒng)諸多屬性定義 App 各種 View 的默認(rèn)樣式,能夠減少 layout 文件中很多重復(fù)性的屬性設(shè)置代碼。在開發(fā)者官網(wǎng) R.attr 欄目中,Google 列出了所有 Android SDK 中的系統(tǒng)級(jí)屬性。如何取舍,如何區(qū)分,又有哪些常用的屬性呢?本文就來列舉顏色相關(guān)的一些屬性介紹,以供參考。
通常,在 res/values/styles.xml 文件中定義的 application 主題樣式里,你可能見到的最常見的使用組合是這樣:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
事實(shí)上,遠(yuǎn)不止這樣...
Theme.AppCompat
自 Lollipop 開始,Android 系統(tǒng)引入 Material Design 風(fēng)格,各個(gè)控件的呈現(xiàn)樣式大有改變。為了在不同版本的系統(tǒng)中統(tǒng)一 UI 樣式,設(shè)置自定義的 Application Theme 的 parent 樣式為 Theme.AppCompat 系列即可。比如這里的 Theme.AppCompat.Light.NoActionBar
主題。
關(guān)于 AppCompat 相關(guān)主題提供的系統(tǒng)屬性,可以參考源碼:v7/appcompat/res/values-v21/themes_base.xml。
同時(shí),由于部分屬性的版本兼容問題,為了避免添加多個(gè)版本的 styles 文件,可以省略 android:
命名空間。
colorPrimary
App Bar 的背景色,即 ActionBar,通常也是一個(gè) App 的主題色調(diào)。不過 ActionBar 已經(jīng)退出歷史舞臺(tái),由 Toolbar 代替使用,但是 Toolbar 需要在 layout 文件中單獨(dú)使用 background 屬性設(shè)置背景色,如:
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary" />
colorPrimaryDark
status bar(狀態(tài)欄)背景色。僅作用于 Lollipop 及更高版本。
colorAccent
許多控件在選中狀態(tài)或獲取焦點(diǎn)狀態(tài)下使用這個(gè)顏色,常見有:
- CheckBox:checked 狀態(tài)
- RadioButton:checked 狀態(tài)
- SwitchCompat:checked 狀態(tài)
- EditText:獲取焦點(diǎn)時(shí)的 underline 和 cursor 顏色
- TextInputLayout:懸浮 label 字體顏色
- 等等
除了這三種常見的控制顏色屬性,事實(shí)上,還有一些顏色相關(guān)的屬性也是非常實(shí)用的。
android:navigationBarColor
navigation bar 背景色。僅作用于 Lollipop 及更高版本。
colorControlNormal
某些 Views “normal” 狀態(tài)下的顏色,常見如:unselected CheckBox 和 RadioButton,失去焦點(diǎn)時(shí)的 EditText,Toolbar 溢出按鈕顏色,等等。
colorControlActivated
某種程度上,是 colorAccent 的替代者,比如對(duì)于 CheckBox 和 RadioButton 的 checked 狀態(tài),colorControlActivated 屬性會(huì)覆蓋 colorAccent 屬性的對(duì)應(yīng)顏色。
colorControlHighlight
所有可點(diǎn)擊 Views 觸摸狀態(tài)下的 Ripple(漣漪)效果。僅作用于 Lollipop 及更高版本。
colorButtonNormal
Button normal 狀態(tài)下的背景色。注意,這種設(shè)置與 Button 的 android:background
屬性改變背景色不同的是,前者在 Lollipop 及更高版本上會(huì)讓 Button 依舊保持陰影和 Ripple 觸摸效果。
android:windowBackground
窗口背景色,諸如此類的還有:android:background
,android:colorBackground
等。
android:textColorPrimary
EditText 的 text color,等等文本顏色。
諸如此類,還有很多顏色相關(guān)的系統(tǒng)屬性。GitHubGist 上面有一份參考指南:Android Lollipop Widget Tinting Guide,列舉了常用控件的著色相關(guān)屬性。
ThemeOverlay.AppCompat
作為 Application Theme 的 parent 主題,Theme.AppCompat 提供了諸多屬性設(shè)置 App 全局 Views 樣式。但是有時(shí)候,我們還是需要單獨(dú)給某個(gè)或者某些 View 設(shè)置與全局樣式不一樣的樣式。這種情況下,ThemeOverlay.AppCompat 就派上用場(chǎng)啦。
正如命名所表達(dá)的含義一般,ThemeOverlay.AppCompat 系列主題用于覆蓋基本的 AppCompat.Theme 樣式,按照需求僅僅改變部分屬性的樣式。這里列舉一些常見用法:
ThemeOverlay.AppCompat
繼承自 @style/Base.ThemeOverlay.AppCompat。這是一個(gè)空主題,但是卻將 AppCompat 主題中的相關(guān)屬性復(fù)制了一遍。這在給個(gè)別 View 單獨(dú)設(shè)置部分樣式時(shí)非常實(shí)用。舉個(gè)例子:
<style name="AppTheme.Secondary" parent="ThemeOverlay.AppCompat">
<item name="colorAccent">@color/colorPrimary</item>
</style>
然后再借助 android:theme
屬性使用在 layout 中的某個(gè) View 上:
android:theme="@style/AppTheme.Secondary"
在這個(gè)例子中,重寫了 colorAccent 屬性,同時(shí)保證其他屬性繼續(xù)延用 parent 為 Theme.AppCompat 的 AppTheme 中的設(shè)置。從 ThemeOverlay.AppCompat 文檔介紹中可以看出,比如 colorPrimary 屬性是這樣復(fù)制的:
android:colorPrimary = ?attr/colorPrimary
如果 parent 使用 Theme.AppCompat 或者其他主題就不行,相當(dāng)于只設(shè)置 colorAccent 屬性,其他屬性使用默認(rèn)樣式。
ThemeOverlay.AppCompat.Light(Dark)
與 ThemeOverlay.AppCompat 不同的是,這個(gè)主題修改背景色、文本顏色、高亮狀態(tài)顏色來匹配 Light(Dark)主題。比如 Light 樣式下的白色背景里,顯示黑色(Dark)文本;Dark 樣式下的黑色背景里,顯示白色(Light)文本。
這個(gè)主題的使用場(chǎng)景可以是這樣,比如我們的全局主題是 Light,但是有一部分 UI 可能需要使用一個(gè) Dark 樣式的背景,這種情況下,每個(gè) View 單獨(dú)設(shè)置顏色就比較麻煩,可以在 ViewGroup 中統(tǒng)一設(shè)置,比如:
<FrameLayout
android:background=”@color/dark_background”
android:theme="@style/ThemeOverlay.AppCompat.Dark”>
<TextView />
</FrameLayout>
ThemeOverlay.AppCompat.Dark.ActionBar
ThemeOverlay.AppCompat.Light.ActionBar
相比而言,由于 Toolbar 的廣泛使用,這對(duì)主題使用的就比較多啦。前面我們說過,colorControlNormal 和 textColorPrimary 屬性都可以影響 Toolbar 或者 ActionBar 的溢出按鈕顏色和溢出文本顏色,同時(shí)也改變著其他 View 的顯示顏色。綜合考慮下,我們不會(huì)使用在 Application Theme 使用這些屬性控制 Toolbar 的內(nèi)容顏色,而是使用這對(duì)主題單獨(dú)設(shè)置給 Toolbar 的 theme 屬性。
比如全局使用的是 Light 主題,Toolbar 的背景色是藍(lán)色或者紅色之類的顏色,要求溢出按鈕的顏色是白色。如果沒有特殊設(shè)置的話,默認(rèn)情況下溢出按鈕顯示為黑色。此時(shí),便可以用上這個(gè)主題:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="?attr/colorPrimary">
</android.support.v7.widget.Toolbar>
總結(jié)
系統(tǒng)主題提供的屬性樣式非常之多,同時(shí)也會(huì)相互影響,多對(duì)多關(guān)系,錯(cuò)綜復(fù)雜,并且有些還會(huì)存在版本兼容問題,使用時(shí)一定要多多測(cè)試。當(dāng)然,使用恰當(dāng)?shù)脑?,能夠減少很多重復(fù)性的 xml 代碼,也方便后續(xù) App 主題變更的需求,拓展之類的場(chǎng)景。