Android Theme.AppCompat 中,你應該熟悉的顏色屬性

亦楓發表於2017-04-20

建立一個 Android 工程,第一步,也是必不可少的一步,就是定製 Application 主題樣式。利用系統諸多屬性定義 App 各種 View 的預設樣式,能夠減少 layout 檔案中很多重複性的屬性設定程式碼。在開發者官網 R.attr 欄目中,Google 列出了所有 Android SDK 中的系統級屬性。如何取捨,如何區分,又有哪些常用的屬性呢?本文就來列舉顏色相關的一些屬性介紹,以供參考。

Android Theme.AppCompat 中,你應該熟悉的顏色屬性

通常,在 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>複製程式碼

事實上,遠不止這樣...

Theme.AppCompat


自 Lollipop 開始,Android 系統引入 Material Design 風格,各個控制元件的呈現樣式大有改變。為了在不同版本的系統中統一 UI 樣式,設定自定義的 Application Theme 的 parent 樣式為 Theme.AppCompat 系列即可。比如這裡的 Theme.AppCompat.Light.NoActionBar 主題。

關於 AppCompat 相關主題提供的系統屬性,可以參考原始碼:v7/appcompat/res/values-v21/themes_base.xml

同時,由於部分屬性的版本相容問題,為了避免新增多個版本的 styles 檔案,可以省略 android: 名稱空間。

colorPrimary

App Bar 的背景色,即 ActionBar,通常也是一個 App 的主題色調。不過 ActionBar 已經退出歷史舞臺,由 Toolbar 代替使用,但是 Toolbar 需要在 layout 檔案中單獨使用 background 屬性設定背景色,如:

<android.support.v7.widget.Toolbar
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="?attr/colorPrimary" />複製程式碼

colorPrimaryDark

status bar(狀態列)背景色。僅作用於 Lollipop 及更高版本。

colorAccent

許多控制元件在選中狀態或獲取焦點狀態下使用這個顏色,常見有:

  • CheckBox:checked 狀態
  • RadioButton:checked 狀態
  • SwitchCompat:checked 狀態
  • EditText:獲取焦點時的 underline 和 cursor 顏色
  • TextInputLayout:懸浮 label 字型顏色
  • 等等

除了這三種常見的控制顏色屬性,事實上,還有一些顏色相關的屬性也是非常實用的。

android:navigationBarColor

navigation bar 背景色。僅作用於 Lollipop 及更高版本。

colorControlNormal

某些 Views “normal” 狀態下的顏色,常見如:unselected CheckBox 和 RadioButton,失去焦點時的 EditText,Toolbar 溢位按鈕顏色,等等。

colorControlActivated

某種程度上,是 colorAccent 的替代者,比如對於 CheckBox 和 RadioButton 的 checked 狀態,colorControlActivated 屬性會覆蓋 colorAccent 屬性的對應顏色。

colorControlHighlight

所有可點選 Views 觸控狀態下的 Ripple(漣漪)效果。僅作用於 Lollipop 及更高版本。

colorButtonNormal

Button normal 狀態下的背景色。注意,這種設定與 Button 的 android:background 屬性改變背景色不同的是,前者在 Lollipop 及更高版本上會讓 Button 依舊保持陰影和 Ripple 觸控效果。

android:windowBackground

視窗背景色,諸如此類的還有:android:backgroundandroid:colorBackground 等。

android:textColorPrimary

EditText 的 text color,等等文字顏色。

諸如此類,還有很多顏色相關的系統屬性。GitHubGist 上面有一份參考指南:Android Lollipop Widget Tinting Guide,列舉了常用控制元件的著色相關屬性。

ThemeOverlay.AppCompat


作為 Application Theme 的 parent 主題,Theme.AppCompat 提供了諸多屬性設定 App 全域性 Views 樣式。但是有時候,我們還是需要單獨給某個或者某些 View 設定與全域性樣式不一樣的樣式。這種情況下,ThemeOverlay.AppCompat 就派上用場啦。

正如命名所表達的含義一般,ThemeOverlay.AppCompat 系列主題用於覆蓋基本的 AppCompat.Theme 樣式,按照需求僅僅改變部分屬性的樣式。這裡列舉一些常見用法:

ThemeOverlay.AppCompat

繼承自 @style/Base.ThemeOverlay.AppCompat。這是一個空主題,但是卻將 AppCompat 主題中的相關屬性複製了一遍。這在給個別 View 單獨設定部分樣式時非常實用。舉個例子:

<style name="AppTheme.Secondary" parent="ThemeOverlay.AppCompat">
    <item name="colorAccent">@color/colorPrimary</item>
</style>複製程式碼

然後再借助 android:theme 屬性使用在 layout 中的某個 View 上:

android:theme="@style/AppTheme.Secondary"複製程式碼

在這個例子中,重寫了 colorAccent 屬性,同時保證其他屬性繼續延用 parent 為 Theme.AppCompat 的 AppTheme 中的設定。從 ThemeOverlay.AppCompat 文件介紹中可以看出,比如 colorPrimary 屬性是這樣複製的:

android:colorPrimary = ?attr/colorPrimary

如果 parent 使用 Theme.AppCompat 或者其他主題就不行,相當於只設定 colorAccent 屬性,其他屬性使用預設樣式。

ThemeOverlay.AppCompat.Light(Dark)

與 ThemeOverlay.AppCompat 不同的是,這個主題修改背景色、文字顏色、高亮狀態顏色來匹配 Light(Dark)主題。比如 Light 樣式下的白色背景裡,顯示黑色(Dark)文字;Dark 樣式下的黑色背景裡,顯示白色(Light)文字。

這個主題的使用場景可以是這樣,比如我們的全域性主題是 Light,但是有一部分 UI 可能需要使用一個 Dark 樣式的背景,這種情況下,每個 View 單獨設定顏色就比較麻煩,可以在 ViewGroup 中統一設定,比如:

<FrameLayout
    android:background=”@color/dark_background”
    android:theme="@style/ThemeOverlay.AppCompat.Dark”>
  <TextView />
</FrameLayout>複製程式碼

ThemeOverlay.AppCompat.Dark.ActionBar
ThemeOverlay.AppCompat.Light.ActionBar

相比而言,由於 Toolbar 的廣泛使用,這對主題使用的就比較多啦。前面我們說過,colorControlNormal 和 textColorPrimary 屬性都可以影響 Toolbar 或者 ActionBar 的溢位按鈕顏色和溢位文字顏色,同時也改變著其他 View 的顯示顏色。綜合考慮下,我們不會使用在 Application Theme 使用這些屬性控制 Toolbar 的內容顏色,而是使用這對主題單獨設定給 Toolbar 的 theme 屬性。

比如全域性使用的是 Light 主題,Toolbar 的背景色是藍色或者紅色之類的顏色,要求溢位按鈕的顏色是白色。如果沒有特殊設定的話,預設情況下溢位按鈕顯示為黑色。此時,便可以用上這個主題:

<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>複製程式碼

總結


系統主題提供的屬性樣式非常之多,同時也會相互影響,多對多關係,錯綜複雜,並且有些還會存在版本相容問題,使用時一定要多多測試。當然,使用恰當的話,能夠減少很多重複性的 xml 程式碼,也方便後續 App 主題變更的需求,擴充之類的場景。

關於我:亦楓,部落格地址:yifeng.studio/,新浪微博:IT亦楓

微信掃描二維碼,歡迎關注我的個人公眾號:安卓筆記俠

不僅分享我的原創技術文章,還有程式設計師的職場遐想

Android Theme.AppCompat 中,你應該熟悉的顏色屬性

相關文章