《Android編程權威指南》之樣式與主題篇

此章的內容比較簡單,學習此章的目的呢,也是為了簡化代碼去美化頁面,定制出APP的獨特風格。

顏色資源

  • res/value中color.xml文件 —— 方便在一處定義各種顏色值供應用引用
截圖取自Demo項目
  • 引用方式 : R.color.xxx
  • 顏色定義方式
    • 三原色:白光 可以分解為 紅、 綠、藍 三種顏色的光, 紅綠藍都是最大值的時候就是白色,三種值相等,但不是最大值是灰色, 如果其中一種或兩種值比較大, 就會產生各種顏色的彩色;
    • 顏色表示:顏色通過紅(red) 綠(green)藍(blue)三種顏色, 以及 透明度(alpha)來表示的;
    • 顏色開頭: 顏色值總是以 # 開頭;
    • 無透明度:如果沒有 alpha 值, 默認完全不透明;
  • 顏色定義形式:
    • RGB: 紅 綠 藍 三原色值,每個值分16個等級, 最小為0,最大為f;
    • ARGB:透明度 紅 綠 藍 值,每個值分16個等級,最小為0,最大為f;
    • RRGGBB:紅 綠 藍 三原色值,每個值分 256個等級, 最小為0,最大為ff;
    • AARRGGBB:透明度 紅 綠 藍 值,每個值分 256個等級,最小為0,最大為ff;

樣式

樣式是一套能夠應用于視圖的屬性,可以為很多組件共用,更新修改屬性時,只修改公共樣式定義即可。

  • 添加樣式(res/values/styles.xml)
截圖取自demo項目
  • 使用樣式
截圖取自demo項目

樣式繼承

樣式支持繼承,一個樣式能繼承并覆蓋其他樣式的屬性。

截圖取自demo

BeatBoxBtn.Strong的命名表示這個新樣式繼承了BeatBoxBtn樣式的屬性

截圖取自demo

指定父樣式的方式也可以表示樣式繼承。

主題

主題可以看作樣式的進化加強版。同樣是定義一套公共主題屬性,樣式屬性需要逐個添加,而主題則會自動應用于整個應用。主題屬性能引用顏色這樣的外部資源,也能引用其他樣式。

修改默認主題

自帶默認主題AndroidManifest.xml文件,application標簽下的theme屬性,指向AppTheme主題,也是定義在styles.xml中。

截圖取自demo
主題實際上就是一種樣式,但是主題指定的屬性有別于樣式。

截圖取自demo
  • AppCompat庫自帶三大主題:
    • Theme.AppCompat —— 深色主題
    • Theme.AppCompat.Light —— 淺色主題
    • Theme.AppCompat.Light.DarkActionBar —— 帶深色工具欄的淺色主題

添加主題顏色

在style.xml中,為AppTheme主題添加三個自定義屬性

截圖取自demo
樣式主題僅適用于單個組件;主題屬性適用于所有使用同一主題的組件。colorPrimary屬性主要用來設置工具欄背景色,也可稱為應用品牌色,colorPrimaryDark用戶屏幕頂部的狀態欄,colorAccent主要用于給EditText這樣的組件著色。注意:只有Lollipop以后的系統支持狀態欄主題顏色。對于之前的系統,無論指定什么主題顏色,狀態欄都是不變的黑底色。

從網上截了個圖,看圖就明白了這些屬性的意思啦!

截圖取自網上

注意,只有Lollipop以后的系統支持狀態欄主題色。對于之前的系統,無論指定什么主題色,狀態欄都是不變的黑底色。

覆蓋主題屬性

主題已經設置了背景色,在此基礎上再設置其他顏色,就是多出來在做額外的工作。而且,在應用里到處復制使用背景屬性設置代碼也不利于后期維護。

  • 主題探秘
    探秘Theme.AppCompat,一層層來看,找到源碼,它是繼承Base.Theme.AppCompat,本身沒有任何屬性。

    Paste_Image.png
    再點進去,多個版本,隨意進了一個:

    Paste_Image.png
    第一個:

    Paste_Image.png
    再進:(部分截圖)

    Paste_Image.png
    可以看到定義了很多屬性,還有注釋,但是沒有找到背景色的屬性,所以繼續,這里也有好幾個版本,隨意選一個,我均選的第一個:

    Paste_Image.png
    這里看到父主題android:Theme,注意不是Theme,而是android:Theme。android命名空間不能丟。
    AppCompat庫可以看作應用的一部分,編譯項目時,工具會引入AppCompat庫和它的一堆Java和XML文件。這些文件已包含在應用里,如同自己編寫的文件。若想引用AppCompat庫里的資源,像Theme.AppCompat這樣,直接引用即可。有些主題包含在Android系統里,引用時必須加上命名空間,如Theme。所以,在引用Theme主題時,AppCompat庫就使用了android:Theme這樣的形式。
    這里已經能找到主題背景色的屬性了:
<item name="android:colorBackground">@color/background_material_dark</item>

再定位到Theme中看看也行(截圖只取部分),也看到了這個屬性:

Paste_Image.png

回到styles.xml文件,覆蓋背景屬性,即可改變整個應用的背景顏色:

Paste_Image.png
我實際操作的主題繼承層次跟此書中的有點改變,想找哪個屬性,按照這種方式找就OK了,截圖均為我實際操作得到。

修改按鈕屬性

可在主題中定義一個用戶所有按鈕的樣式,剛剛Base.V7.Theme.AppCompat中和Theme中均有buttonStyle屬性,即應用中普通按鈕的樣式。

Base.V7.Theme.AppCompat
Theme

Theme中Widget.Button

應用中所有按鈕都使用了這些屬性。
修改按鈕的父樣式,根據需求,有選擇性的修改一些屬性。

Paste_Image.png

然后修改主題的buttonStyle屬性:


Paste_Image.png

搞定。
注意,定義buttonStyle時,沒有使用android:前綴。這是因為,要覆蓋的buttonStyle屬性是在AppCompat庫里實現的。

深入學習:樣式繼承拾遺

要以主題名的形式指定父主題,有繼承關系的兩個主題都應處于同一個包中。因此,對于Android操作系統內部主題間的繼承,就可以直接使用主題名繼承表示法。同理,AppCompat庫內部也是這樣。然而,一旦AppCompat庫要跨庫繼承,就一定要使用parent屬性。

開發自己應用時,如果是繼承自己內部的主題,使用主題名指定父主題即可;如果是繼承Android操作系統中的樣式或主題,記得使用parent屬性。

深入學習:引入主題屬性

在主題定義好屬性后,可以在XML或代碼中直接使用它們。

Paste_Image.png
上述中?符號的意思是使用colorAccent屬性指向的資源。這里指定義在colors.xml中的粉色。

代碼中使用主題屬性比較啰嗦:

Resources.Theme theme = getActivity().getTheme();
        int[] attrsToFetch = {R.attr.colorAccent};
        TypedArray a = theme.obtainStyledAttributes(R.style.AppTheme, attrsToFetch);
        int accentColor = a.getInt(0, 0);
        a.recycle();

先取得Theme對象,然后要求它找到定義在AppTheme(即R.style.AppTheme)中的R.attr.colorAccent屬性。結果得到一個持有數據的TypedArray對象。接著,像TypedArray對象索要int值以取出顏色即可使用了。

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

推薦閱讀更多精彩內容