一些關於style和attr的使用問題

原文:http://blog.csdn.net/wanjf_912/article/details/7641184

  1. 對style和attr的引用

  2. 如何自定義屬性

  3. 如何使用平臺自帶的屬性

  4. 如何繼承style

  5. “android:”前出現‘@’和‘?’的區別

在引用和自定義style和attr時經常會遇到諸如如何引用和自定義style和attr的問題,現總結如下(不斷完善中… …)。

一 、對style和attr的引用

  1. 當引用平臺的style做爲style的parent時,“@android:style/主題” == “@android:主題” ==“ android:style/主題 ”== “android:主題”;
  2. 當引用平臺的style作爲屬性的引用時,“@android:style/主題”;
  3. 當引用自定義style作爲其他style的parent時,“@style/主題” == “style/主題” == “主題”;
  4. 當引用自定義style作爲其他屬性的引用時,“@style/主題”;
  5. 當引用平臺屬性作爲屬性的引用時,“?android:attr/屬性” == “?android:屬性”;
  6. 當引用自定義屬性時,“?attr/屬性” == “?屬性”;
  7. 上述六個情況中,可以在’@’或’?’後加入’*’以引用被隱藏(即平臺私有)的資源;
  8. 如果引用平臺資源或屬性時,可以將“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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章