Android開發(fā) - 樣式和主題

樣式和主題(Styles and Themes)

一個樣式(Style)是一個包含了指定樣子和格式的作用于視圖控件(View)或者窗體(Window)屬性集合。一個style可以指定很多屬性,比如 高度,填充,字體顏色,字體尺寸,背景色等。一個Style在xml資源文件中定義,并且和在xml中指定的布局區(qū)分開來。

在Android里的樣式和Web設計中的CSS共享一個相似的原理,它們允許你分離設計(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" />

所有關聯(lián)到style的屬性已經(jīng)在布局xml中被刪除了,并且放在一個叫做“CodeFont”style中定義了。它通過一個style屬性被應用上。在下面的章節(jié),你將會看到如何定義style。

一個主題(Theme)也是一個style,它被應用在所有的Activity或者application上,而不是個別的視圖控件(View)(像上面的示例一樣)。當一個style被當做一個theme來應用,每一個activity或者application中的視圖控件將應用每一個它支持的樣式屬性。比如,你可以在activity上使用相同的CodeFont樣式作為一個theme,這時Activity里的所有內(nèi)部字體將會變成CodeFont樣式的字體樣式變成綠色的等寬字體。

定義一個樣式Style

為了創(chuàng)建一些樣式,你可以保存在你的工程下的 res/Values/ 文件夾下的一個XML文件中。XML文件的名字是隨意的,但是必須擴展名是 .xml 并且存放在 res/Values/ 文件夾下。

XML文件的根節(jié)點必須是<resources>

為你創(chuàng)建的每個樣式,添加一個<style>元素,并且需要一個name 屬性,它標識唯一性而且是必需的屬性。再為你的樣式屬性都添加進去,通過添加<item>元素來做,使用一個在樣式屬性里聲明的name屬性和一個value屬性,這兩個都是必需的。<item>的value屬性可以是一個關鍵字字符串,一個16進制的顏色描述,一個其他資源類型的引用,或者在其他樣式屬性中依賴的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é)點在編譯時都被轉(zhuǎn)換成一個程序資源對象。它可以通過<style>元素的name屬性的值(value)來被引用引用。這個示例樣式可以在XML布局中被引用,比如“@style/CodeFont”(像上面介紹的示例一樣)。

在<style>元素中的parent屬性是可選的并且指向一個其他樣式中的資源ID,它可以從這個樣式中繼承一些屬性。合適的話,你可以重寫(override)繼承到的屬性。

記住,一個你想在activity或者application中使用的樣式都被在XML文件中定義,并且所有的視圖控件具有相同的樣式。一個樣式,比如上面定義的那個,可以被作為一style應用的單一的視圖控件上或者被作為一個theme應用在全部的activity或者application上。如何應用的單一的視圖或者作為應用的主題,我們稍后討論。

繼承

在<style>中的parent屬性讓你可以指定一個你可以繼承其屬性的樣式。你可以使用這個從一個已經(jīng)存在的樣式中繼承屬性,并且定義一些獨有的你需要改變或者添加的屬性。你可以繼承那些來自你已經(jīng)自行創(chuàng)建的樣式或者或者繼承自在平臺里構(gòu)建好的樣式(See Using Platform Styles and Themes,下面,獲得關于繼承安卓平臺樣式的更多信息)。比如,你可以繼承安卓平臺默認的字體樣式并且修改它,比如:

  <style name="GreenText" parent="@android:style/TextAppearance">
        <item name="android:textColor">#00FF00</item>
    </style>

如果你想要繼承你自己創(chuàng)建的樣式,你不需要一定適用parent屬性。作為替代,可以為一個你想繼承的樣式的名字構(gòu)建前綴而作為你的新的樣式的名稱,中間用“點”隔開。比如,為了創(chuàng)建一個樣式,比如繼承自上面的CodeFont樣式,但是讓顏色變成紅色,你可以這樣寫你的新樣式:

<style name="CodeFont.Red">
        <item name="android:textColor">#FF0000</item>
    </style>

注意<style>標簽沒有parent屬性,但是,因為name屬性是以CodeFont(這是個你已經(jīng)定義好的樣式)這個樣式名開始的,這個樣式從哪個樣式里繼承了所有的樣式屬性。這個樣式這里覆蓋里android:textColor屬性,將文本改成了紅色。你可以引用這個新的樣式比如@style/CodeFont.Red

你可以繼續(xù)這樣繼承很多次,使用“點”鏈接這些名稱,比如,你可以擴展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)在,你明白了如何定義一個樣式,你需要去學會 在<item>元素下什么類型被定義的樣式屬性是可用的。你可能已經(jīng)熟悉了很多已經(jīng)有的,比如layout_width 和 textColor. 當然,還有很多的樣式屬性你可以使用。

尋找可以應用在指定視圖控件上的屬性的最好的地方是 相應的類引用,它列出了所有支持的XML屬性。比如所有在表格 TextView XML attributes 中列出的屬性,都可以應用在一個樣式的定義中作用在TextView元素上(或者它的子類)。在 引用 中被列出的一個屬性叫做android:inputType的,這樣你可以再<EditText>元素中應用這個屬性,像下面這樣:

<EditText
    android:inputType="number"
    ... />

你可以為EditText 元素創(chuàng)建一個樣式,包含這個屬性,來代替上面:

<style name="Numbers">
  <item name="android:inputType">number</item>
  ...
</style>

這樣你的布局用的XML能夠這樣實現(xiàn)樣式:

<EditText
    style="@style/Numbers"
    ... />

這個簡單的示例看起來多做了一些工作,不過當你添加更多的樣式屬性并且把在多處可重用樣式的能力作為參考因素的話,你的付出將是值得的。

獲得所有可用樣式的屬性的引用(reference),請參閱 R.attr 引用。記住,所有的視圖控件對象不接受所有相同的屬性,這樣你可以平常的引用圖為視圖控件類指定支持的樣式屬性。然而,如果你為某個視圖控件應用了一個樣式,這個樣式包含的屬性中不是都被支持的,視圖控件將會應用那些屬性中的可被支持的并且簡單的忽略其他的。

一些樣式屬性,不被支持在視圖控件里使用,僅僅能作為主題使用。那些樣式屬性應用在所有的窗體上,不能用在任何視圖控件上。比如有些樣式屬性可以隱藏應用程序的標題,隱藏狀態(tài)條,或者更改窗體的背景。那些類型的樣式屬性不屬于任何視圖控件對象。要發(fā)現(xiàn)更多 僅僅作用于theme主題 的屬性,查看R.attr 引用中的以windows開始的屬性。比如,windowNoTitle 和 windowBackground 屬性只能在應用于activity和application時發(fā)生作用。參閱下一章節(jié)可以獲得更多“在theme中應用樣式”的內(nèi)容。

注意:在<item>元素中,不要忘記寫屬性名稱的前綴 android: ,這是一個命名空間,比如:<item name="android:inputType">.

在UI上應用樣式和主題

有兩種方式設置一個樣式:

  1. 為單個視圖控件指定樣式,在XML布局文件中的視圖元素上添加style屬性。
  2. 為整個activity或者application指定樣式,在manifest.xml中的<activity>或者<application>節(jié)點元素中添加 android:theme 屬性。

當你為布局里的單個控件中應用一個樣式,你的樣式中定義的屬性都會應用在這個視圖組件中。如果你的樣式應用在一個ViewGroup中,它的所有子控件元素將不能繼承這些樣式的屬性,只有你直接指定的那個視圖元素可以應用這些屬性。不過,你仍然可以通過主題的方式為你的應用下的所有視圖元素應用樣式。

要想應用一個主題,你必須在manifest.xml中為activity或者aplication上應用樣式。當你這么做,每一個Activity或者aplication里的視圖元素都將應用這些樣式中它支持的屬性。比如,如果應用上面提到的CodeFont樣式在一個Activity上,這是所有的支持文本樣式屬性的視圖元素將應用它們。一些不支持這些屬性的視圖元素將忽略它們。如果一個視圖支持一部分屬性,那么它將只應用這些屬性。

在視圖元素中應用樣式

下面演示如何在XML布局中設置一個樣式:

<TextView
    style="@style/CodeFont"
    android:text="@string/hello" />

現(xiàn)在 TextView將具有樣式,像CodeFont定義的屬性描述的一樣。你可以參考上面的示例。

注意:樣式style 不需要使用android: 命名空間前綴。

在activity或者application中應用樣式

要想再你的所有activity或者application上使用樣式,打開 AndroidManifest.xml 并且修改<application>標簽,讓它包含 android:theme 屬性并指定一個樣式名稱,比如:

    <application android:theme="@style/CustomTheme">

如果你想為你的應用中的某個activity使用樣式,那么添加 android:theme 到你的<activity>標簽中。

安卓提供了一些內(nèi)置資源,你可以使用這些預先定義好的樣式,而不用自己再重新寫了。比如,你可以使用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>

注意上面用到的顏色在其他資源中被提供,這里,因為android:windowBackground 屬性僅僅支持其他資源的引用,不像 android:colorBackground屬性可以指定一個顏色描述文本。

現(xiàn)在,在你的Mnaifest文件中,可以使用 CustomTheme 代替 Theme.Light:

<activity android:theme="@style/CustomTheme">

選擇一個平臺支持的樣式作為基礎

安卓較新的版本為應用提供了額外的可用的樣式,同時你可能想要使用它們在那些平臺上運行,并且仍然和老版本保持兼容。你可以通過自定樣式做到,使用“資源選擇器"來切換不同的父主題,基于平臺版本。

比如,下面是一個自定義樣式的聲明,這個樣式是個簡單的標準平臺默認的 light theme主題。它可能被放置在res/valeus文件夾下的 XML文件中(經(jīng)典的是在 res/values/styles.xml)。

<style name="LightThemeSelector" parent="android:Theme.Light">
    ...
</style>

當應用跑在Android 3.0(API級別11)或者更高以上時,可以讓這個樣式使用較為新一些的holo風格主題,你可以放置一個可供選擇的聲明樣式防止在res/values-v11這個文件夾下的XML文件中,但是讓這個樣式繼承自 holo風格的主題:

<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
    ...
</style>

現(xiàn)在可以像任意其他那樣來使用這個主題,并且當跑在安卓3.0以上時,你的應用程序會自動切換到holo風格的主題。

在 R.styleable.Theme. 里,可以找到一個標準的屬性列表供你使用。

關于更多的信息,像比如主題和布局,基于平臺版本或者設備配置等切換資源文件選擇,你可以閱讀 Providing Resources 。

使用平臺樣式和主題

安卓平臺提供了很多樣式和主題,供你在應用程序中使用。在 R.style 類里你可以找到可以用的引用。為了使用這里列出的樣式,你可以使用”點“替換所有的下劃線分割的 樣式名稱,比如,你可以通過”"@android:style/Theme.NoTitleBar".來使用 Theme_NoTitleBar 樣式。

R.style 引用,然而,不是和好的文件記錄,并且不能全面的描述樣式,那么查看那些樣式和主題的實際的資源代碼可以給你更好一些關于”各個被提供樣式屬性“的的理解。獲得更多關于樣式和主題的引用,你可以看下面的源代碼:

Android Styles (styles.xml)
Android Themes (themes.xml)

那些文件將通過實例幫助你學習。比如,在安卓的主題源代碼中,你將找到一個聲明 <style name="Theme.Dialog">.在這些定義里,你將會看到所有的常常用到的 ”被用于安卓框架的樣式對話框的屬性“

更多關于 樣式和主題 在XML中的語法的信息,請參閱 Style Resource 文檔。

對于 一個可用的樣式屬性的引用,你可以它使用定義一個樣式或者主題(比如"windowBackground" 或者 "textAppearance),在你創(chuàng)建一個樣式時你可以閱讀 R.attr 或者各自的視圖類。

本文翻譯自:https://developer.android.com/guide/topics/ui/themes.html

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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