天天看點

對AttributeSet和defStyle的了解

    在通過xml檔案構造view元件的時候,往往都要使用到attributeset和defstyle這個兩個參數,例如button元件的構造方法button(context ctx, attributeset attrs, int defstyle)中,ctx會調用obtainstyledattributes( attributeset set, int[] attrs, int defstyleattr, int defstyleres)方法獲得一個typedarray,然後根據這個typearray來設定元件的屬性。obtainstyledattributes這類方法有好幾個,真正的實作是resources.theme類,分别是:

     (1) obtainstyledattributes( attributeset set, int[] attrs, int defstyleattr, int defstyleres) : typedarray

     (2) obtainstyledattributes( int resid, int[] attrs)  : typearray

     (3) obtainstyledattributes(int[] attrs) : typearray

     在方法(1)裡根據attrs确定要擷取哪些屬性,然後依次通過其餘3個參數來取得相應的屬性值,屬性值擷取的優先級從高到低依次是set, defstyleattr, defstyleres. defstyleattr是一個reference, 它指向目前theme中的一個style, style其實就是各種屬性的集合,如果defstyleattr為0或者在theme中沒有找到相應的style, 則 才會嘗試從defstyleres擷取屬性值,defstyleres表示的是一個style的id,

當它為0時也無效。方法(2)和(3)分别表示從style或theme裡擷取屬性值。

    attr是在/res/values/attrs.xml檔案下定義的,除了系統元件本身的屬性,我們也可以自定義屬性,然後在layout布局中使用。attrs.xml裡通常包括若幹個attr集合,例如

    <declare-styleable name="labelview">

        <attr name="text" format="string" />

        <attr name="textcolor" format="color" />

        <attr name="textsize" format="dimension" />

    </declare-styleable>

    就表示一個attr集合,declare-styleable标簽裡的name值表示的就是上面方法裡的attrs參數,android會自動在r檔案中生成一個數組, 它可以使任意的不一定要是view元件名稱。在集合裡定義每個屬性的名稱和它的類型,據偶所見總共有reference, string, color, dimension, boolean等,如果允許多個類型可以用"|"來隔開,比如reference | color, attr還可以這樣定義

    <attr name="layout_height" format="dimension">

       <enum name="fill_parent" value="-1" />

       <enum name="match_parent" value="-1" />

       <enum name="wrap_content" value="-2" />

    </attr>

當attr的定義沒有指明format時,表示它已經在其他地方定義過了,是以你可以定義一個attr集合,裡面的都是已經定義好的屬性(例如系統元件的屬性), 然後通過obtainstyledattributes方法來擷取這些屬性值,例如

    <declare-styleable name="gallery1">

        <attr name="android:galleryitembackground" />

在layout布局中使用自定義的屬性,要指明包名稱,需要先定義,例如xmlns:app="http://schemas.android.com/apk/res/your_package_name", 然後就可以這樣app:text, app:textsize來設定屬性了。

   r檔案中會有styleable和attr這兩個類,當我們要使用哪個屬性集合或哪個屬性的時候用的是styleable, 而attr類定義的僅僅是attr這個屬性在layout中的id. attributeset有兩個方法分别是

    int getattributenameresource(int index);

    int getattributeresourcevalue(int index, int defaultvalue);

     前一個方法擷取的就是attr屬性名稱的id,也也就是attr類定義的數值,後一個方法擷取的才是attr屬性值。

繼續閱讀