- Android經(jīng)典應(yīng)用程序開發(fā)
- 韓超編著
- 329字
- 2019-01-09 15:18:51
2.6 樣式和主題的使用
Android中,樣式(Style)是一種用于描述一組屬性的機(jī)制,可以應(yīng)用于控件(View)或者窗口。
樣式通常有兩種使用方法:
(1)在布局文件中將其應(yīng)用于控件標(biāo)簽,此時(shí)通常依然稱之為樣式(style)。
(2)在AndroidManifest.xml中將其應(yīng)用于一個(gè)Activity或者一個(gè)application,此時(shí)通常稱之為主題(Theme)。此時(shí)相當(dāng)于將這個(gè)樣式應(yīng)用于其中的所有控件。
樣式可以使用系統(tǒng)的預(yù)置的定義,也可以自定義。預(yù)定義使用R.style類,自定義樣式通常在一個(gè)XML文件中使用<style>標(biāo)簽來描述。
2.6.1 控件中的樣式
控件的樣式讓布局文件中的眾多控件擁有相同的屬性,使用樣式不僅可以減少布局文件中重復(fù)的內(nèi)容,也有利于全局控制控件的外觀等公共屬性。
Android中預(yù)定義的樣式,使用R.style類中的各個(gè)成員來表示。樣式的本質(zhì)是對(duì)各個(gè)XML屬性進(jìn)行定義,這些XML屬性在Android中使用R.attr類來表示。
每個(gè)控件的style屬性可以用于設(shè)置它的樣式,在布局文件中可以使用類似style="@android:style/MediaButton"的方式。
例如,在某個(gè)布局文件中一個(gè)控件的定義如下所示:
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#00FF00" android:typeface="monospace" android:text="@string/hello" />
此時(shí)如果認(rèn)為除了android:text之外的屬性都是作為公共的內(nèi)容實(shí)現(xiàn)的,可以利用樣式將這個(gè)控件寫成如下方式:
<TextView style="@style/CodeFont" android:text="@string/hello" />
此時(shí)的style屬性被設(shè)置為名稱為CodeFont的樣式。可以使用res/values/目錄中的styles.xml文件進(jìn)行定義,內(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>
這里進(jìn)行的自定義樣式CodeFont繼承了Android預(yù)置的樣式TextAppearance.Medium,并且定義了android:textColor等幾個(gè)屬性。定義完成后可以在各個(gè)布局文件中使用。
2.6.2 全局性質(zhì)的主題
在AndroidManifest.xml中使用android:theme屬性來表示設(shè)置一種樣式作為全局性的內(nèi)容。<application>和<activity>標(biāo)簽具有這個(gè)屬性。此時(shí)應(yīng)用的樣式中的內(nèi)容,對(duì)其中的所有內(nèi)容都起作用。
Android預(yù)置的主題來自android.R.style中的Theme_*等常量。除了預(yù)置的主題,可以繼承預(yù)定義樣式實(shí)現(xiàn)自定義主題,也可以生成完全的自定義主題。
提示:主題和樣式在本質(zhì)上是相同的,都是對(duì)XML文件中的一組屬性進(jìn)行默認(rèn)的定義。在Android中,應(yīng)用于控件時(shí)稱之為樣式(Style),應(yīng)用于活動(dòng)和應(yīng)用時(shí)稱之為主題(Theme),后者通常比前者多了一些和窗口屬性相關(guān)的定義。
主題的設(shè)置也可以在代碼中使用,這種方式并不常用。Activity的父類ContextThemeWrapper中具有如下的方法:
public void setTheme (int resid)
1.預(yù)定義主題
android.R.style類中有屬性常量名稱為Theme_Light_NoTitleBar_Fullscreen,那么在AndroidManifest.xml使用的就是如下的格式:
需要將“_”替換成“.”,然后可以在AndroidManifest.xml中使用。大多數(shù)預(yù)定義樣式都有子類,Theme.<style>.NoTitleBar表示使用該樣式加無標(biāo)題欄的效果,Theme.<style>.NoTitleBar.Fullscreen表示使用該樣式加全屏的效果。
使用不同樣式示例程序:Controls(ApiDemo=>Views=>Controls)
源代碼:
com/example/android/apis/view/Controls1.java com/example/android/apis/view/Controls2.java
布局文件:controls_1.xml
使用不同樣式的示例程序如圖2-19所示。

圖2-19 使用不同樣式的示例程序(左:Theme.Light樣式;右:默認(rèn)樣式)
兩個(gè)活動(dòng)使用同樣的布局文件,兩個(gè)活動(dòng)的內(nèi)容基本是相同的,運(yùn)行的效果卻是一個(gè)白底色一個(gè)黑底色。它們的主要區(qū)別體現(xiàn)在AndroidManifest.xml中,如下所示:
<activity android:name=".view.Controls1" android:label="Views/Controls/1. Light Theme" android:theme="@android:style/Theme.Light"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity> <activity android:name=".view.Controls2"
android:label="Views/Controls/2. Default Theme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity>
第二個(gè)程序使用了默認(rèn)樣式,而第一個(gè)程序使用了"@android:style/Theme.Light",表示使用的是Theme.Light樣式,在這種情況下底色變成了淺色的效果。
在Activity的代碼中進(jìn)行的樣式設(shè)置如下所示:
protected void onCreate(Bundle savedInstanceState) { setTheme(android.R.style.Theme_NoTitleBar); super.onCreate(savedInstanceState); // ......省略活動(dòng)的創(chuàng)建過程 }
對(duì)于代碼中的樣式設(shè)置,由于執(zhí)行場(chǎng)合不同,因此即使將設(shè)置的代碼放在Activityd的onCreate()方法的最前面,也不能保證和在AndroidManifest.xml中設(shè)置的效果相同。
2.自定義主題
根據(jù)預(yù)定義樣式,可以通過繼承的方法實(shí)現(xiàn)自定義的樣式。這種自定義樣式通常只改變預(yù)定義樣式的部分屬性,一般可以在res/values/styles.xml文件中通過<style>標(biāo)簽來完成定義,然后將其設(shè)置到AndroidManifest.xml中的android:theme屬性。此時(shí)使用的是類似android:theme="@style/MyTheme"的格式。
參考程序?yàn)橐粋€(gè)對(duì)話框樣式的活動(dòng)和一個(gè)自定義對(duì)話框樣式的活動(dòng)。
示例程序:
DialogActivity(ApiDemo=>App=>Activity=> DialogActivity) CustomDialogActivity(ApiDemo=>App=>Activity=>CustomDialogActivity)
源代碼:com/example/android/apis/app/DialogActivity.java
布局文件:custom_dialog_activity.xml
樣式文件:res/values/styles.xml
兩個(gè)活動(dòng)運(yùn)行結(jié)果如圖2-20所示。

圖2-20 預(yù)定樣式和自定義樣式實(shí)現(xiàn)類似對(duì)話框的活動(dòng)運(yùn)行結(jié)果
上述兩個(gè)程序本質(zhì)上都是活動(dòng),但是顯示的效果卻類似于一個(gè)對(duì)話框。透過對(duì)話框透明的部分,可以看到下面的活動(dòng)。
這兩個(gè)程序的布局文件和源代碼都并無特別的地方。效果是通過在AndroidManifest.xml中設(shè)置其樣式android:theme來完成的。
AndroidManifest.xml中的定義如下所示:
<activity android:name=".app.DialogActivity" android:label="@string/activity_dialog" android:theme="@android:style/Theme.Dialog" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity> <activity android:name=".app.CustomDialogActivity" android:label="@string/activity_custom_dialog" android:theme="@style/Theme.CustomDialog“ > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity>
DialogActivity將樣式設(shè)置為“@android:style/Theme.Dialog”,表示使用預(yù)定義的樣式Theme.Dialog。
CustomDialogActivity將樣式設(shè)置為“@style/Theme.CustomDialog”,表示使用名稱為Theme.CustomDialog的自定義樣式。
CustomDialog是一個(gè)自定義樣式,在res/values/styles.xml中進(jìn)行定義,如下所示:
<style name="Theme.CustomDialog" parent="android:style/Theme.Dialog"> <item name="android:windowBackground">@drawable/filled_box</item> </style>
使用“parent”表示由CustomDialog本身繼承的預(yù)定義樣式,重新定義了窗口的背景為drawable中的filled_box。這里引用了filled_box.xml文件,這個(gè)文件在res/drawable中,其中定義了相關(guān)內(nèi)容。在定義的樣式中,通過設(shè)置更多的值來獲得不同的窗口效果。通過自定義樣式文件可以獲得復(fù)用效果。
提示:類似的對(duì)話框場(chǎng)景,前臺(tái)的程序沒有覆蓋住整個(gè)屏幕,此時(shí)后面依然處于可見狀態(tài)的活動(dòng)是onPause()狀態(tài),通常情況下,活動(dòng)是完全被遮擋的,處于onStop()狀態(tài)。
3.完全自定義樣式作為主題
樣式可以在程序中全新定義,通過定制各個(gè)屬性進(jìn)行定義。這些屬性來自于R.attr類中的內(nèi)容進(jìn)行定義。具體每一個(gè)屬性可以使用的值,可以從R.attr類的幫助文檔中找到。
由于繼承主題的方式實(shí)際上使用的是“單繼承”,因此如果想組合主題,隨心所欲地設(shè)置效果,最終的方式還是直接設(shè)置屬性。
例如,如果在res/values/styles.xml中定義如下內(nèi)容:
<style name="Theme.WindowTranslucent "> <item name="android:windowIsTranslucent">true</item> </style>
定義名稱為Theme.WindowTranslucent的樣式,表示背景透明的效果。這里進(jìn)行自定義的windowIsTranslucent就是R.attr類的一個(gè)成員。雖然主題只能繼承一個(gè),但是可以進(jìn)行多數(shù)量屬性的設(shè)置。
在Android程序中,當(dāng)某一個(gè)活動(dòng)啟動(dòng)之后,可能需要使用背景透明的效果,本例用于描述背景透明的應(yīng)用。
參考示例程序:
TranslucentActivity(ApiDemo=>App=>Activity=>Translucent) TranslucentBlurActivity(App=>Activity=>TranslucentBlur)
源代碼:
com/example/android/apis/app/TranslucentActivity.java com/example/android/apis/app/TranslucentBlurActivity.java
樣式文件:values/styles.xml
透明程序的運(yùn)行結(jié)果如圖2-21所示。

圖2-21 TranslucentActivity和TranslucentBlurActivity程序的運(yùn)行結(jié)果
AndroidManifest.xml中的定義如下所示:
<activity android:name=".app.TranslucentActivity" android:label="@string/activity_translucent" android:theme="@style/Theme.Translucent“ > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity> <activity android:name=".app.TranslucentBlurActivity" android:label="@string/activity_translucent_blur" android:theme="@style/Theme.Transparent“ > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter>
</activity>
兩個(gè)活動(dòng)分別使用Theme.Translucent和Theme.Transparent主題,它們都是自定義的主題,內(nèi)容在values/styles.xml中。
Theme.Translucent主題如下所示:
<style name="Theme.Translucent" parent="android:style/Theme.Translucent"> <item name="android:windowBackground"> @drawable/translucent_background</item> <item name="android:windowNoTitle">true</item> <item name="android:colorForeground">#fff</item> </style>
Theme.Transparent主題如下所示:
<style name="Theme.Transparent"> <item name="android:windowIsTranslucent">true</item> <item name="android:windowAnimationStyle"> @android:style/Animation.Translucent</item> <item name="android:windowBackground"> @drawable/transparent_background</item> <item name="android:windowNoTitle">true</item> <item name="android:colorForeground">#fff</item> </style>
Theme.Transparent實(shí)際上是一個(gè)沒有繼承預(yù)定義主題的主題,在其中自定義了windowIsTranslucent和windowAnimationStyle屬性,取得了和繼承Theme.Translucent類似的效果,并且使用了windowNoTitle表示設(shè)置為沒有標(biāo)題欄。
兩個(gè)主題使用的背景數(shù)值在colors.xml中定義,如下所示:
<drawable name="translucent_background">#e0000000</drawable> <drawable name="transparent_background">#00000000</drawable>
除此之外,TranslucentBlurActivity之所以能夠獲得背景模糊的效果,是因?yàn)樵谠创a中進(jìn)行了進(jìn)一步的設(shè)置,如下所示:
public class TranslucentBlurActivity extends Activity { protected void onCreate(Bundle icicle) { super.onCreate(icicle); getWindow(). // 獲得窗口,用以設(shè)置其中的特性 setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND, WindowManager.LayoutParams.FLAG_BLUR_BEHIND); setContentView(R.layout.translucent_background); } }
設(shè)置模糊效果是通過窗口管理器設(shè)置參數(shù)來完成的,這種設(shè)置只有在背景設(shè)置為透明后才能顯示效果。
- 數(shù)字電路知識(shí)與實(shí)踐課堂
- 元器件應(yīng)用電路全掌握(雙色版)
- Android音視頻開發(fā)
- Protel DXP 2004電路設(shè)計(jì)基礎(chǔ)與典型范例
- 通信專業(yè)綜合能力與實(shí)務(wù):終端與業(yè)務(wù)
- 上門速查快修新型VCD/DVD機(jī)500例
- 信息論與編碼原理
- iOS游戲框架Sprite Kit技術(shù)詳解
- 天地一體化信息網(wǎng)絡(luò)時(shí)間統(tǒng)一技術(shù)
- 海纜工程建設(shè)管理程序與實(shí)務(wù)
- 射頻與微波晶體管功率放大器工程
- 5G產(chǎn)業(yè):新智能時(shí)代革命
- 應(yīng)用電工電子技術(shù)(上冊(cè))
- 空間信號(hào)協(xié)同處理理論與技術(shù)
- 新一代無線技術(shù)頻譜分配機(jī)制與應(yīng)用