【Android XML】Android XML 轉 Java Code 系列之 style(3),androidxml

來源:互聯網
上載者:User

【Android XML】Android XML 轉 Java Code 系列之 style(3),androidxml

最近一個月把代碼重構了一遍, 感覺舒服多了, 但總體開發進度沒有變化.. 今天聊聊把style屬性轉換成Java代碼的辦法

 

先說結論: 引用系統style是無法完美的實現的, 我們如果有寫成Java代碼的需求, 請盡量避免使用系統style. 自訂style沒問題.

 

style是什麼?

 (參考連結) http://developer.android.com/guide/topics/resources/style-resource.html

" A style resource defines the format and look for a UI. A style can be applied to an individual View (from within a layout file) or to an entireActivity or application (from within the manifest file)."

更通俗的理解是, style其實是放置一組attribute的宏, 在控制項中指定這個style, 將在xml解析時將style的一組屬性應用到該控制項中. 舉個栗子:

這裡有個style, 定義在res/value中:

<?xml version="1.0" encoding="utf-8"?><resources>    <style name="CustomText" parent="@style/Text">        <item name="android:textSize">20sp</item>        <item name="android:textColor">#008</item>    </style></resources>

然後我們在layout中的某個控制項引用了這個style:

<?xml version="1.0" encoding="utf-8"?><EditText    style="@style/CustomText"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:text="Hello, World!" />

 

實際上, 他是等於: 

<?xml version="1.0" encoding="utf-8"?><EditText    android:textSize="20sp"    android:textColor="#008"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:text="Hello, World!" />

有點宏替換的味道, 如果接觸過html的同學可以很容易想到CSS這種東西, 兩個想要做的基本是一樣的.

需要指明的是: style的屬性的優先順序是最低的, 會被控制項的其他相同屬性覆蓋掉. 這是理所當然的, 不然控制項裡的attribute要不服了(你都把我寫出來了, 居然和我說我沒用, 要被style那貨覆蓋掉?!)

 

讓我們再回到這個被我們定義的style上, 會發現他還有一個叫parent的屬性. 這裡我們用物件導向的父類來理解, 就是子style會繼承父類的屬性. 同樣的, 父類的屬性要比子類屬性優先順序要低. (你都把我寫出來了, 居然和我說我沒用, 要被老爸的style覆蓋掉?!)

 

style不是什麼?

style不屬於android Namespace中的屬性 (不以android:開頭), 沒有對應的setStyle方法可以使用, 我的理解是它屬於xml預先載入的一種"機制".

 

自訂style的翻譯:

那麼對於自訂的style, 翻譯就很簡單了. 

對於一個style, 將其替換成style中的attribute集合, 並向上 (父類) 繼續增加父類集合, 並注意優先順序 (子類可以覆蓋父類attribute).

 

系統style的翻譯:

系統style的翻譯主要存在兩個問題:

1. 系統style是內建在系統內部的, 不同的系統style並不一樣, 特別是深度定製化的如MIUI, Flyme等作業系統. 如果只是使用一些簡單的比較標準的style, 如progressbar等, 可以通過SDK Manager下載最新Android版本的API, 然後在路徑platforms\android-20\data\res\values中找到標準的系統style, 或直接下載ASOP(路徑framework/base/core/res/res/values/styles.xml. (我在項目中用到的是4.4的style檔案, 5.0的sytle檔案分成了多個, 而且裡面的命名有點不規範)

  有些同學會發現, 如progressbar裡面的style: android:attr/progressBarStyleSmall, 是用android:attr索引的. android:attr其實是在theme中定義的屬性, apk的theme在AndroidManifest.xml中定義. 在解析xml過程中, 遇到android:attr的時候, 他就會在apk指定的theme中找到相應的item. 這個item對應的值就是style的值, 如:

style=?android:attr/progressBarStyleSmall對應 最基本的Theme中的<item name="progressBarStyleSmall">@android:style/Widget.ProgressBar.Small</item>

然後你再去styles.xml中尋找Widget.ProgressBar.Small. (這裡還有個要注意的是, 就是系統的style不會聲明parent屬性, 但是以點"."做層級, 比如這裡的Widget.ProgressBar.Small父類是Widget.ProgressBar)

這樣帶來的另一個問題, 深度定製的作業系統各種主題也會有改動, 這樣造成更大的偏差.

 

2. 系統style用到的資源, 有些是我們從外部無法擷取的. 還是舉Widget.ProgressBar.Small的例子:

    <style name="Widget.ProgressBar.Small">        <item name="android:indeterminateDrawable">@android:drawable/progress_small_white</item>        <item name="android:minWidth">16dip</item>        <item name="android:maxWidth">16dip</item>        <item name="android:minHeight">16dip</item>        <item name="android:maxHeight">16dip</item>    </style>

他裡面用到了@android:drawable/progress_small_white這個系統資源, 但是這個資源不是public的, 我們實現的時候沒辦法把這個資源調用出來. 有些同學會想到反射, 但反射也是不行的. 因為所有的系統資源在ASOP編譯的時候會產生類似於R.java這樣的資源索引檔案, 這些檔案用於我們使用系統資源的id來調用系統資源. 而非public是不會聲明出來的, 也就是說你連id都無法知道, 也就無法擷取對應資源了. 我曾大致閱讀了一下xml的解析實現, 發現到最後都進入了native層, 在native層用c/c++實現, 這讓我望code興歎..

不過ProgressBar的各種樣式應該可以通過api來設定出來, 這個我還沒證實. 可以參考: [Android執行個體] Android 在Java代碼中設定style屬性--使用代碼建立ProgressBar對象 

對這個非public系統資源擷取有經驗的同學歡迎交流.

 

項目代碼:

我在項目中實現了構建style元素, 使用style元素替換為attritutes, 以及style元素之間的關係, 包括對theme的android:attr尋找:

https://github.com/SickWorm/AndroidXMLToJava/blob/master/src/com/excelsecu/androidx2j/AX2JStyle.java

 

著作權,轉載請註明出處:

http://www.cnblogs.com/sickworm/p/4355396.html

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.