以下整理一下Android resource核心的觀念跟作法,android resource其實也是一個複雜的東西,包含Style與Theme的撰寫,兩者的差異在哪,
以下列出幾點問題如果可以釐清,我想對於應該就已經攻破android resource了。
1.Resource有哪些,String、Color、boolean.......
2.各個名詞解釋,style、theme、attr是什麼,要能夠口頭敘述出來。
2.AttributeSet跟TypedArray是什麼? 兩者有什麼關聯性,在程式碼中怎麼使用。
3.Styleable是什麼,跟style有關嗎?




@attr

1.什麼是attr
一個<attr>單元有兩屬性:name以及format。
name就是這個<attr>的名字,可以讓他在別的地方被參考到。 
format表示這個<attr>是符合哪一種格式。
formate可用格式有:
    • reference - if it references another resource id (e.g, "@color/my_color", "@layout/my_layout")
    • color
    • boolean
    • dimension
    • float
    • integer
    • string
    • fraction
    • enum - normally implicitly defined
    • flag - normally implicitly defined


如下例所示: 
layout_width這個屬性宣告在ViewGroup_Layout裡,


<declare-styleable name="ViewGroup_Layout">
                           .....
        <attr name="layout_width" format="dimension">
            <enum name="fill_parent" value="-1" />
            <enum name="match_parent" value="-1" />
            <enum name="wrap_content" value="-2" />
        </attr>
</declare-styleable>

@Style
Style:是一個包含一種或者多種格式化屬性的集合,我們可以將其用為一個單位用在佈局XML單個元素當中。比如,我們可以定義一種風格來定義文字的字體大小和顏色,然後將其用在TextView的樣式設定上。
如下定義了兩種文字的style
<?xml version=”1.0″ encoding=”utf-8″?> 
<resources> 
<style name=”DavidStyleText1″> 
<item name=”android:textSize”>18sp</item > 
<item name=”android:textColor”>#EC9237</item> 
</style> 
<style name=”DavidStyleText2″> 
<item name=”android:textSize”>14sp</item> 
<item name=”android :textColor”>#FF7F7C</item> 
<item name=”android:fromAlpha”>0.0</item> 
<item name=”android:toAlpha”>0.0</item> 
</style> 
</resources>
可以套用在不同的TextView上,
<!–應用樣式1的TextView –> 
<TextView 
style=”@style/DavidStyleText1″ 
android:layout_width=”fill_parent” 
android:layout_height=”wrap_content” 
android:gravity=”center_vertical|center_horizontal” 
android:text=”moandroid” />
<!–應用樣式2的TextView –> 
<TextView 
style=”@style/DavidStyleText2″ 
android:layout_width=”fill_parent” 
android:layout_height=”wrap_content” 
android:gravity=”center_vertical|center_horizontal” 
android:text=”www. moandroid.com” 
android:autoLink=”all”/>

@Theme

Theme:是一個包含一種或者多種格式化屬性的集合,我們可以將其為一個單位用在應用程式裡所有的Activity當中(即Application)或者應用程式裡的某個Activity。比如,我們可以定義一個Theme,它為window frame和panel 的前景和背景定義了一組顏色,並為Menu定義文字的大小和顏色屬性,可以將這個Theme應用在你應用程序當中所有的Activity裡。

跟style差別在於:
不同的是透過在Android Manifest中定義的<application>和<activity>元素將主題添加到整個程序或者某個Activity,但是主題是不能應用在某一個單獨的View裡。

例子如下所示:
<?xml version=”1.0″ encoding=”UTF-8″?> 
<resources> 
<style name=”NewTheme” parent=”android:Theme.Black”> 
<item name=”android:windowNoTitle”>true</ item> 
<item name=”android:textSize”>14sp</item> 
<item name=”android:textColor”>#FFFF0000</item> 
</style> 
</resources>



@Styleable
1.什麼是Styleable
涵義是"可以樣式化的"。從程式碼角度來看,所謂的樣式和之前所說得style基本上沒有關係,實際上styleable只是在R.java中增加一個 int[ ]陣列而已, aapt為每一個attr分配一個指定的id值,這個陣列的內容正是該styleable所包含的所有attr的id值。
<declare-styleable name="Window">
    <attr name="windowBackground" />
    <attr name="windowContentOverlay" />
    <attr name="windowFrame" />
     <attr name="windowNoTitle" />
</declare-styleable>

name後面可以使用任何的名稱,若是在Window中宣告了某個attr,就不能在其他的stylable中再次宣告,
要注意宣告跟引用的差別,若是在attr後面僅有一個name,而沒有format,那就是引用,否則就是宣告,且只能有一個宣告,但可以有多個引用。


2.Styleable使用時機
若只使用attr,則當要從一個屬性陣列中取得所感興趣的某些屬性值就會顯得有些繁瑣,如下所示:
<ElementName
attr_name1="value1"
attr_name2="value2"
....
attr_nameN="valueN"
/>

當XML解析時,會返回一個AttributeSet物件,包含element元素定義的所有屬性和值,從attr_name1到attr_nameN。若是只想取某幾個attr_name屬性的值,必須使用attrbuteSet的API並根據相對應的id來取出,這樣實在不太方便。因此,才有Styleable,可以把某幾個需要的屬性放在一個styleable裡,

<declare-styleable name="Flower">
    <attr name="attr_name2" />
    <attr name="attr_name4" />
    <attr name="attr_name5" />
</declare-styleable>

這樣的話,當從AttributeSet物件中取得這三個屬性時,就可以把R.styleable.Flower作為參數,該參數實際上會被aapt編譯成一個int[ ] 陣列,陣列的內容正是所含的attr的id,本質上與不用styleable是相同的。



@AttributeSet
1.什麼是AttributeSet
是一個輔助類別,僅僅是為了解析XML檔案之用。

<ElementName
attr_name1="value1"
attr_name2="value2"
....
attr_nameN="valueN"
/>

透過AttributeSet類別提供的API,可以方便的根據attr.xml中已有的名稱取得相對應的值。

2.如何取得
AttributeSet是作為View的建構函數的參數傳遞過來,只需在建構函數中透過該物件的API取得相應的屬性值即可。比如,TextView的建構函數如下所示:
TextView(Context context, AttributeSet attrs, int defStyle);
 假定XML格式如下:
<View class="android.widget.TextView"
   android:layout_width="@dimen/general_width"
   android:layout_height="wrap_content"
   android:text="@string/hello"
   android:id="@+id/output"
   style="@style/Text"
/>

AttributeSet的API可按功能分為下列幾個類別:
(1)操作特定屬性
a. String getIdAttribute() : 取得id屬性對應的字串,返回值為"@+id/output"

(2)操作通用屬性
a. int getAttributeCount() : 取得屬性的數目,本例中return 6。
b.String getAttributeName(int index): 根據屬性所在的位置返回相對應的屬性名稱。
class=0
layout_width=1
....

(3)取得特定類型的值
a. XXXType getAttributeXXXTypeValue(int index, XXXType defaultValue)
這個XXXType包括int, boolean, float等類型,但使用此方法時,需明確知道某個位置(index)相對應
的資料類型,否則會返回錯誤。



@TypedArray
1.什麼是TypedArray
若是只有AttributeSet,開發者還需用其繁複的API來取得屬性設定的值,很是麻煩,
譬如若是取得@dimen/general_width類型的字串,還需解析這個具體的dimen的值為何。
因此可以透過TypedArray,提供更方便的方法直接取得該dimen值


2.如何得到TypeArray
TypedArray a = context.obtainStyledAttributes(attrs,  R.styleable.MyView, defStyle, 0); 
第一個參數attr是一個AttributeSet的物件,包含了一個XML元素中所定義的所有屬性。
第二個參數就是前面定義的Styleable,aapt會把一個styleable編譯為一個int[]陣列,該陣列所包含的內容
正是stylable中所包含的attr對應的id值,它代表使用所感興趣的屬性名稱。

此函數內部實現正是透過瀏覽AttributeSet中的每一個屬性,找到使用者感興趣的屬性,然後把值跟屬性經過
重新定位,返回一個TypedArray物件。

<declare-styleable name="Window">
     <attr name="windowBackground" />  
     <attr name="windowContentOverlay" />
     <attr name="windowFrame" />
     <attr name="windowNoTitle" />
</declare-styleable>

TypedArray有下列的成員變數
(1) int[] mData
(2)TypedValue,是一個資料類別,意義是為了儲存一個屬性值,比如layout_width、textSize、textColor等

接著再透過a->getDrawable()或a->getString()取得該style定義的圖片或字串。

如下面客製化Button的例子:

public TextButton(final Context context, AttributeSet attrs) { 
    this(context, attrs, 0); 
    TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.button); 
    this.setTextSize(typedArray.getDimension(R.styleable.button_textSize, 15)); 
    typedArray.recycle();

將獲取自定義textSize的值,如果沒有,則使用默認的值,15。
arrow
arrow
    全站熱搜

    cloudfly 發表在 痞客邦 留言(1) 人氣()