- Android經(jīng)典應(yīng)用程序開發(fā)
- 韓超編著
- 199字
- 2019-01-09 15:18:51
2.6 樣式和主題的使用
Android中,樣式(Style)是一種用于描述一組屬性的機制,可以應(yīng)用于控件(View)或者窗口。
樣式通常有兩種使用方法:
(1)在布局文件中將其應(yīng)用于控件標(biāo)簽,此時通常依然稱之為樣式(style)。
(2)在AndroidManifest.xml中將其應(yīng)用于一個Activity或者一個application,此時通常稱之為主題(Theme)。此時相當(dāng)于將這個樣式應(yīng)用于其中的所有控件。
樣式可以使用系統(tǒng)的預(yù)置的定義,也可以自定義。預(yù)定義使用R.style類,自定義樣式通常在一個XML文件中使用<style>標(biāo)簽來描述。
2.6.1 控件中的樣式
控件的樣式讓布局文件中的眾多控件擁有相同的屬性,使用樣式不僅可以減少布局文件中重復(fù)的內(nèi)容,也有利于全局控制控件的外觀等公共屬性。
Android中預(yù)定義的樣式,使用R.style類中的各個成員來表示。樣式的本質(zhì)是對各個XML屬性進行定義,這些XML屬性在Android中使用R.attr類來表示。
每個控件的style屬性可以用于設(shè)置它的樣式,在布局文件中可以使用類似style="@android:style/MediaButton"的方式。
例如,在某個布局文件中一個控件的定義如下所示:
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#00FF00" android:typeface="monospace" android:text="@string/hello" />
此時如果認(rèn)為除了android:text之外的屬性都是作為公共的內(nèi)容實現(xiàn)的,可以利用樣式將這個控件寫成如下方式:
<TextView style="@style/CodeFont" android:text="@string/hello" />
此時的style屬性被設(shè)置為名稱為CodeFont的樣式。可以使用res/values/目錄中的styles.xml文件進行定義,內(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>
這里進行的自定義樣式CodeFont繼承了Android預(yù)置的樣式TextAppearance.Medium,并且定義了android:textColor等幾個屬性。定義完成后可以在各個布局文件中使用。
2.6.2 全局性質(zhì)的主題
在AndroidManifest.xml中使用android:theme屬性來表示設(shè)置一種樣式作為全局性的內(nèi)容。<application>和<activity>標(biāo)簽具有這個屬性。此時應(yīng)用的樣式中的內(nèi)容,對其中的所有內(nèi)容都起作用。
Android預(yù)置的主題來自android.R.style中的Theme_*等常量。除了預(yù)置的主題,可以繼承預(yù)定義樣式實現(xiàn)自定義主題,也可以生成完全的自定義主題。
提示:主題和樣式在本質(zhì)上是相同的,都是對XML文件中的一組屬性進行默認(rèn)的定義。在Android中,應(yīng)用于控件時稱之為樣式(Style),應(yīng)用于活動和應(yīng)用時稱之為主題(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)樣式)
兩個活動使用同樣的布局文件,兩個活動的內(nèi)容基本是相同的,運行的效果卻是一個白底色一個黑底色。它們的主要區(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>
第二個程序使用了默認(rèn)樣式,而第一個程序使用了"@android:style/Theme.Light",表示使用的是Theme.Light樣式,在這種情況下底色變成了淺色的效果。
在Activity的代碼中進行的樣式設(shè)置如下所示:
protected void onCreate(Bundle savedInstanceState) { setTheme(android.R.style.Theme_NoTitleBar); super.onCreate(savedInstanceState); // ......省略活動的創(chuàng)建過程 }
對于代碼中的樣式設(shè)置,由于執(zhí)行場合不同,因此即使將設(shè)置的代碼放在Activityd的onCreate()方法的最前面,也不能保證和在AndroidManifest.xml中設(shè)置的效果相同。
2.自定義主題
根據(jù)預(yù)定義樣式,可以通過繼承的方法實現(xiàn)自定義的樣式。這種自定義樣式通常只改變預(yù)定義樣式的部分屬性,一般可以在res/values/styles.xml文件中通過<style>標(biāo)簽來完成定義,然后將其設(shè)置到AndroidManifest.xml中的android:theme屬性。此時使用的是類似android:theme="@style/MyTheme"的格式。
參考程序為一個對話框樣式的活動和一個自定義對話框樣式的活動。
示例程序:
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
兩個活動運行結(jié)果如圖2-20所示。

圖2-20 預(yù)定樣式和自定義樣式實現(xiàn)類似對話框的活動運行結(jié)果
上述兩個程序本質(zhì)上都是活動,但是顯示的效果卻類似于一個對話框。透過對話框透明的部分,可以看到下面的活動。
這兩個程序的布局文件和源代碼都并無特別的地方。效果是通過在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是一個自定義樣式,在res/values/styles.xml中進行定義,如下所示:
<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文件,這個文件在res/drawable中,其中定義了相關(guān)內(nèi)容。在定義的樣式中,通過設(shè)置更多的值來獲得不同的窗口效果。通過自定義樣式文件可以獲得復(fù)用效果。
提示:類似的對話框場景,前臺的程序沒有覆蓋住整個屏幕,此時后面依然處于可見狀態(tài)的活動是onPause()狀態(tài),通常情況下,活動是完全被遮擋的,處于onStop()狀態(tài)。
3.完全自定義樣式作為主題
樣式可以在程序中全新定義,通過定制各個屬性進行定義。這些屬性來自于R.attr類中的內(nèi)容進行定義。具體每一個屬性可以使用的值,可以從R.attr類的幫助文檔中找到。
由于繼承主題的方式實際上使用的是“單繼承”,因此如果想組合主題,隨心所欲地設(shè)置效果,最終的方式還是直接設(shè)置屬性。
例如,如果在res/values/styles.xml中定義如下內(nèi)容:
<style name="Theme.WindowTranslucent "> <item name="android:windowIsTranslucent">true</item> </style>
定義名稱為Theme.WindowTranslucent的樣式,表示背景透明的效果。這里進行自定義的windowIsTranslucent就是R.attr類的一個成員。雖然主題只能繼承一個,但是可以進行多數(shù)量屬性的設(shè)置。
在Android程序中,當(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
透明程序的運行結(jié)果如圖2-21所示。

圖2-21 TranslucentActivity和TranslucentBlurActivity程序的運行結(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>
兩個活動分別使用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實際上是一個沒有繼承預(yù)定義主題的主題,在其中自定義了windowIsTranslucent和windowAnimationStyle屬性,取得了和繼承Theme.Translucent類似的效果,并且使用了windowNoTitle表示設(shè)置為沒有標(biāo)題欄。
兩個主題使用的背景數(shù)值在colors.xml中定義,如下所示:
<drawable name="translucent_background">#e0000000</drawable> <drawable name="transparent_background">#00000000</drawable>
除此之外,TranslucentBlurActivity之所以能夠獲得背景模糊的效果,是因為在源代碼中進行了進一步的設(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ù)
- 電子元器件檢測技能1+1點撥
- 移動互聯(lián)網(wǎng)技術(shù)架構(gòu)及其發(fā)展(修訂版)
- LED顯示屏組裝與調(diào)試全攻略
- Altium DXP 2004電路設(shè)計
- 步步圖解電子元器件應(yīng)用與檢測技能
- 手繪圖說數(shù)字電路圖
- 基于FBMC/OQAM的海上無線通信技術(shù)
- 信息通信業(yè)的數(shù)字化發(fā)展之路
- 精通Android 5 多媒體開發(fā)
- 電子技術(shù)及應(yīng)用
- 陣列信號處理及MATLAB實現(xiàn)(第2版)
- 5G網(wǎng)絡(luò)全專業(yè)規(guī)劃設(shè)計寶典
- 動手指,知天下:老年人學(xué)用智能手機
- 電子組裝工藝可靠性