本篇提到的方法,是通過更改應用應用主題中的style的屬性,來使得自定義布局可以應用到全局。
更改theme默認顏色
Theme是應用到整個application或activity的樣式,其實也是一種style,只不過比較龐大。使用api 25新建module,默認使用繼承與“Theme.AppCompat.Light.DarkActionBar”的“AppTheme”主題,并更改了三個顏色屬性。AppTheme定義在module的values/styles.xml中。更改這三個顏色,發現分別對應app的標題欄、手機頂欄和組件默認顏色。將三者分別改為紅、綠、藍三色,以下是代碼及對應的界面:
事實上,這三個屬性是在最底層的Theme樣式中定義的,因此可以應用到全部組件。
自定義全局組件
既然可以通過更改colorAccent來改變所有組件的顏色,那么肯定可以通過類似的方式,定義組件樣式,并在全局使用。下面來自定義一個全局button。可以想到,應該有一個屬性,是用來指定button樣式的,只要重為這個屬性賦值即可。事實上,這些屬性都是屬于android.R.attr的,具體的說明可見官方文檔R.attr。而自定義button,需要使用buttonStyle屬性。
默認Button樣式
buttonStyle的具體樣式也是在Theme中指定的:<item name="buttonStyle">@style/Widget.Button</item>
。順便說下Theme樣式的定義可以在C:\Users\【username】\AppData\Local\Android\sdk\platforms\android-xx\data\res\values
中找到。Widget.Button定義如下:
<style name="Widget.Button">
<item name="background">@drawable/btn_default</item>
<item name="focusable">true</item>
<item name="clickable">true</item>
<item name="textAppearance">?attr/textAppearanceSmallInverse</item>
<item name="textColor">@color/primary_text_light</item>
<item name="gravity">center_vertical|center_horizontal</item>
</style>
其中@drawable/btn_default的定義如下:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_normal_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_default_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_normal_disable_focused" />
<item
android:drawable="@drawable/btn_default_normal_disable" />
</selector>
這之中的drawable文件已經無法右鍵go to declaration了,所以是圖片文件。可在C:\Users\【username】\AppData\Local\Android\sdk\platforms\android-xx\data\res\drawable-mdpi
中找到對應的圖片。默認樣式如下:
自定義Button樣式
在module的style.xml中自定義樣式,并用其重定義buttonStyle屬性:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="buttonStyle">@style/MyButtonStyle</item>
</style>
<style name="MyButtonStyle" parent="@android:style/Widget.Button">
<item name="android:background">#0000ff</item>
</style>
由于默認樣式是Widget.Button,因此這里直接繼承它,然后更改希望更改的屬性。這樣不想更改的屬性就不需要再自己定義一遍。這里把background屬性重定義成藍色。然后在應用的AppTheme樣式中,將buttonStyle屬性指定為自定義的MyButtonStyle樣式。注意,使用系統的style或屬性,名稱前要使用"android:"。完成后布局中button的樣式如下:
以這種方式,類似地,可以將所有組件更改為自定義樣式。而且就buttonStyle來說,我們已經知道此屬性定義在Theme這個style中,因此在所有基于Theme的樣式中,都可以使用這種方法,而不擔心沒有對應的屬性。