原文:http://blog.csdn.net/wanjf_912/article/details/7641184
對style和attr的引用
如何自定義屬性
如何使用平臺自帶的屬性
如何繼承style
“android:”前出現‘@’和‘?’的區別
在引用和自定義style和attr時經常會遇到諸如如何引用和自定義style和attr的問題,現總結如下(不斷完善中… …)。
一 、對style和attr的引用
- 當引用平臺的style做爲style的parent時,“@android:style/主題” == “@android:主題” ==“ android:style/主題 ”== “android:主題”;
- 當引用平臺的style作爲屬性的引用時,“@android:style/主題”;
- 當引用自定義style作爲其他style的parent時,“@style/主題” == “style/主題” == “主題”;
- 當引用自定義style作爲其他屬性的引用時,“@style/主題”;
- 當引用平臺屬性作爲屬性的引用時,“?android:attr/屬性” == “?android:屬性”;
- 當引用自定義屬性時,“?attr/屬性” == “?屬性”;
- 上述六個情況中,可以在’@’或’?’後加入’*’以引用被隱藏(即平臺私有)的資源;
- 如果引用平臺資源或屬性時,可以將“android:”放在斜槓“/”的後面,即,@android:style/主題”== @style/android:主題”,“?android:attr/屬性”== “?attr/android:屬性”;
二、 如何自定義屬性
<resources>
<attr name="anr">
<enum name="none" value="0" />
<enum name="thumbnail" value="1" />
<enum name="drop" value="2" />
</attr>
</resources>
這種方式定義屬性後,其他的塊內可以直接使用,但不能帶有任何名字或格式說明,e.g:
<declare-styleable name="TextView">
<attr name="anr">
</declare-styleable>
下面是錯誤的:
<declare-styleable name="TextView">
<attr name="anr" format="string">
</declare-styleable>
因爲這相當於重新定義了”anr”,這是不允許的。因此,塊外出現的屬性優先於塊內出現的屬性,即,如果塊內出現某一帶有format描述的屬性,而塊外也有一個同名屬性(沒有format說明),則是錯誤的。
此外,如果對首次出現在內的屬性指定了format,則其他的內可直接使用這個屬性,但不能再指定其他format。這種情況類似於使用首次出現塊外的屬性。
因此,在塊外的屬性最好都指明format說明,以便爲塊內使用。
e.g:
如果,
<resources>
<attr name="anr" />
</resources>
然後,
<declare-styleable name="TextView">
<attr name="anr" format="dimension">
</declare-styleable>
或者
<declare-styleable name="TextView">
<attr name="anr">
<enum name="none" value="0" />
<enum name="thumbnail" value="1" />
<enum name="drop" value="2" />
</attr>
</declare-styleable>
這些都是錯誤的!
2:
<declare-styleable name="Theme">
<attr name="colorText" format="color|reference"/>
<attr name="colorForeground" format="color"/>
<attr name="colorForegroundInverse" format="color"/>
</declare-styleable>
這種方式定義屬性的前提是此前沒有對colorText, colorForeground,colorForegroundInverse的任何定義。同第一種一樣,以後的塊內可以直接使用,但不能再做其他改動,e.g:
<declare-styleable name="TextView">
<attr name="colorText">
</declare-styleable>
或者:
<declare-styleable name="TextView">
<attr name="colorText">
<attr name="colorForeground">
</declare-styleable>
但下面是錯誤的:
<declare-styleable name="TextView">
<!--不能再有format="color|reference"說明-->
<attr name="colorText" format="color|reference">
<attr name="colorForeground">
</declare-styleable>
三、 如何使用平臺自帶的屬性
e.g:
<declare-styleable name="FragmentArguments">
<!--不能有格式說明-->
<attr name="android:label" />
</declare-styleable>
此時,在R.styleable內部會有個屬性的定義,名爲FragmentArguments_android_label。
但是,不能對平臺自帶的屬性重新定義,e.g:
<resources>
<attr name="android:label" />
</resources>
但可以這樣:
<resources>
<attr name="label" format="string"/>
</resources>
四、 如何繼承style
可以使用點‘.’和“parent”來繼承自定義的style,而要想繼承平臺style,則只能使用“parent”。
e.g:
1.
<style name="HelloTheme" parent="@android:style/Theme.Light" >
<item name="colorForeground">#770000</item>
<item name="colorBackground">#000000</item>
<item name="colorText">#00ff00</item>
<item name="android:windowBackground" >@drawable/windowoverlay </item>
<item name="android:windowNoTitle">false</item>
</style>
2.
<style name="HelloTheme" parent="HelloTheme.MyHelloTheme">
<item name="windowBackground" >@drawable/overlaybk </item>
<item name="colorText">#00ff00</item>
</style>
<style name="HelloTheme.Hello" >
<!--<item name="android:background">?attr/windowBackground</item>-->
<!--<item name="android:textColor">?attr/colorText</item>-->
<item name="android:background">?windowBackground</item>
<item name="android:textColor">?colorText</item>
</style>
3.
<style name="Holo">
<item name="textViewStyle">@style/HelloTheme.Hello</item>
</style>
4.
<style name="Holo.TextViewStyle" />
如果對一個TextView使用Holo.TextViewStyle時,不會起到任何作用。應該直接使用:
<style name="TextViewStyle">
<item name="android:background">?windowBackground</item>
<item name="android:textColor">?colorText</item>
</style>
或者
<style name="TextViewStyle_1" parent="TextViewStyle" >
或者
<style name="TextViewStyle.TextViewStyle_1">
由此可知,屬性引用(reference)可以傳遞,當然前提是應用或活動的主題(theme)中使用了windowBackground和colorText,上例中:
<item name="android:background">?windowBackground</item>
<item name="android:textColor">?colorText</item>
等價於:
<item name="android:background">@drawable/overlaybk</item>
<item name="android:textColor">#00ff00</item>
因爲,windowBackground和colorText作爲兩個屬性的引用,在這裏已被設置:
<style name="HelloTheme" parent="HelloTheme.MyHelloTheme">
<item name="windowBackground" >@drawable/overlaybk </item>
<item name="colorText">#00ff00</item>
</style>
自定義屬性時,在parent處指定的繼承平臺已有屬性時偶爾會提示資源不存在
e.g:
parent="@android:style/TextAppearance.Holo.Light.Inverse"
error: Error retrieving parent for item: No resource found that matches the given name '@android:style/TextAppearance.Holo.Light.Inverser'.
這種寫法是錯誤的,雖然平臺下的data/res/styles.xml內有該屬性的定義,但是平臺的android.R.style類內並不存在TextAppearance_Holo_Light_Inverse,因爲此類屬性是平臺的私有屬性,不公開的。所以,也不能使用android.R.style.TextAppearance_Holo_Light_Inverse.
若要避免錯誤,可以這樣書寫:parent=”@*android:style/TextAppearance.Holo.Light.Inverse” ,或去掉’@’和(或)’style/’。
最後,如果style的名字內既出現了點‘.’,也使用“parent”,則該style只繼承了parent指向的style,style的 “name”裏的‘.’不會起作用。如果在style的”name”內出現了‘.’,而又沒有使用”parent”,則name裏的點’.’之前的名字必須存在定義。而如果使用了parent,name內點’.’之前的任何名字可以不存在定義。
五、 “android:”前出現‘@’和‘?’的區別
在定義style時經常會遇到此類情況,例如:
<style name="Theme.IconMenu" parent="Theme.Holo">
<!-- Menu/item attributes -->
<item name="android:itemTextAppearance">@android:style/TextAppearance.Widget.IconMenu.Item</item>
<item name="android:itemBackground">?android:attr/selectableItemBackground</item>
<item name="android:itemIconDisabledAlpha">?android:attr/disabledAlpha</item>
<item name="android:horizontalDivider">@android:drawable/divider_horizontal_dark</item>
<item name="android:verticalDivider">@android:drawable/divider_vertical_dark</item>
<item name="android:windowAnimationStyle">@android:style/Animation.OptionsPanel</item>
<item name="android:moreIcon">@android:drawable/ic_menu_more</item>
<item name="android:background">@null</item>
</style>
其中,@android:style/TextAppearance.Widget.IconMenu.Item表明”android:itemTextAppearance”爲一個style類型,它引用了平臺的另一個style(TextAppearance.Widget.IconMenu.Item)。而 ?android:attr/disabledAlpha則表明”android:itemIconDisabledAlpha”的屬性值引用當前主題下的disabledAlpha。