The NoteBook of EricKong

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

          declare-styleable:declare-styleable是給自定義控件添加自定義屬性用的。

          官方的相關(guān)內(nèi)部控件的配置屬性文檔:http://developer.android.com/reference/android/R.styleable.html


          如果不知道如何查看源碼:點(diǎn)擊這里


          起初,在自定義控件的時(shí)候,會(huì)要求構(gòu)造3個(gè)方法中的一個(gè)或多個(gè),好比我自定義的控件PersonView,

          1. public PersonView(Context context) {  
          2.         super(context);  
          3.         // TODO Auto-generated constructor stub  
          4.     }  
          5.   
          6.     public PersonView(Context context, AttributeSet attrs, int defStyle) {  
          7.         super(context, attrs, defStyle);  
          8.         // TODO Auto-generated constructor stub  
          9.     }  
          10.   
          11.     public PersonView(Context context, AttributeSet attrs) {  
          12.         super(context, attrs);  
          13. }  
          其中的AttributeSet attrs一般都沒(méi)給它配置和使用,所以不知道這個(gè)東西到底怎么用,后來(lái)查看源碼發(fā)現(xiàn),這個(gè)配置在默認(rèn)情況下使用的是系統(tǒng)自己的默認(rèn)配置,一旦你直接設(shè)定了它的屬性,默認(rèn)屬性就會(huì)被你的賦值所替代。

          下面我們拿TextView的源碼看看AttributeSet是如何進(jìn)行操作的。

          初始化時(shí)候,在布局文件中寫android:text="拉拉";



          初始化TextView的時(shí)候,它的類中的屬性都會(huì)初始化;




          接著往下看,你可以看到以下代碼:


          1. TypedArray a = theme.obtainStyledAttributes(  
          2.             attrs, com.android.internal.R.styleable.TextViewAppearance, defStyle, 0);  
          3. TypedArray appearance = null;  
          4. int ap = a.getResourceId(  
          5.         com.android.internal.R.styleable.TextViewAppearance_textAppearance, -1);  
          6. a.recycle();  
          7. if (ap != -1) {  
          8.     appearance = theme.obtainStyledAttributes(  
          9.             ap, com.android.internal.R.styleable.TextAppearance);  
          這個(gè)就是系統(tǒng)在默認(rèn)的資源文件R.styleable中去獲取相關(guān)的配置。

          如果appearance不為空,它就會(huì)去尋找獲取相關(guān)屬性,接著往下看。


          此時(shí)的text = "";     就是準(zhǔn)備輸出的字符串初始化。

          之后它便會(huì)查找你布局文件XML中是否設(shè)定給了它text屬性值


          之前我們?cè)O(shè)定過(guò)android:text="拉拉";  所以它便會(huì)得到相關(guān)的賦值,之后調(diào)用

          1. <span style="font-size:18px;"> setText(text, bufferType);  
          2.  if (hint != null) setHint(hint);  
          3. </span>  
          輸出該字符串。當(dāng)資源檢查賦值完畢后,調(diào)用a.recycle();釋放。
          同理也可以發(fā)現(xiàn),像hint,textcolor這類屬性都是這么初始化賦值的。


          思路:

          自定義控件并且自定義屬性的情況下,你可以通過(guò)這樣去獲取判斷是否配置了相關(guān)的屬性,并進(jìn)行賦值操作。


          從源碼那邊我們大體知道了一個(gè)控件的屬性配置和初始化流程,下面就讓我們按照這個(gè)思路去自己學(xué)習(xí)下如何自定義配置。


          下面我要寫一個(gè)繼承了TextView的PersonView類,給它設(shè)定屬性配置,之后實(shí)現(xiàn)屬性的顯示。

          1.首先,先寫attrs.xml

          在res-vlaues文件夾下創(chuàng)建資源文件attrs.xml或則自定義一個(gè)資源文件xx.xml,都可以。

          之后在里面配置declare-styleable ,name為PersonAttr

          1. <?xml version="1.0" encoding="utf-8"?>  
          2. <resources>  
          3.     <declare-styleable name="PersonAttr">  
          4.         <attr name="name" format="reference" />  
          5.         <attr name="sex" format="reference" />  
          6.         <attr name="age" format="integer" />  
          7.         <attr name="weight">  
          8.             <flag name="fat" value="2" />  
          9.             <flag name="mid" value="1" />  
          10.             <flag name="thin" value="0" />  
          11.         </attr>  
          12.         <attr name="adult" format="boolean" />  
          13.         <attr name="textSize" format="dimension" />  
          14.     </declare-styleable>  
          15. </resources>  

          我這里設(shè)置了姓名name,性別sex,年齡age,以及特征屬性weight(fat,mid,thin內(nèi)部的3個(gè)屬性及對(duì)應(yīng)的屬性值),還有是否成年adult,和TextView的字體大小textView。

          可能這里有人會(huì)問(wèn),format是什么,里面的單詞代表的又是什么意思。

          format就是格式,里面的就是這個(gè)屬性對(duì)應(yīng)的格式,下面列出來(lái)大致的格式有:

          1. reference:參考某一資源ID,以此類推

          (1)屬性定義:

          <declare-styleable name = "名稱">

          <attr name = "background" format = "reference" />

          </declare-styleable>

          (2)屬性使用:

          <ImageView

          android:layout_width = "42dip"

          android:layout_height = "42dip"

          android:background = "@drawable/圖片ID"

          />

          2. color:顏色值

          <declare-styleable name = "名稱">

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

          </declare-styleable>

          3. boolean:布爾值

          <declare-styleable name = "名稱">

          <attr name = "focusable" format = "boolean" />

          </declare-styleable>

          4. dimension:尺寸值。注意,這里如果是dp那就會(huì)做像素轉(zhuǎn)換

          <declare-styleable name = "名稱">

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

          </declare-styleable>

          5. float:浮點(diǎn)值。

          6. integer:整型值。

          7. string:字符串

          8. fraction:百分?jǐn)?shù)。

          9. enum:枚舉值

          10. flag:是自己定義的,類似于 android:gravity="top",就是里面對(duì)應(yīng)了自己的屬性值。

          11. reference|color:顏色的資源文件。
          12.reference|boolean:布爾值的資源文件

          注意://由于reference是從資源文件中獲取:所以在XML文件中寫這個(gè)屬性的時(shí)候必須 personattr:name="@string/app_name"這種格式,否則會(huì)出錯(cuò)


          2.設(shè)置好屬性文件后,在使用的布局中寫相關(guān)配置:

          1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
          2.     xmlns:personattr="http://schemas.android.com/apk/res/com.example.declare_styleable"  
          3.     android:layout_width="match_parent"  
          4.     android:layout_height="match_parent" >  
          5.   
          6.     <com.example.declare_styleable.PersonView  
          7.         android:layout_width="wrap_content"  
          8.         android:layout_height="wrap_content"  
          9.         personattr:name="@string/person_name"   
          10.         personattr:weight ="fat"  
          11.         personattr:adult ="false"  
          12.         personattr:textSize="@dimen/text_size"/>  
          13.   
          14. </RelativeLayout>  

          這里要先應(yīng)用這個(gè)attr:
          1. xmlns:personattr="http://schemas.android.com/apk/res/com.example.declare_styleable"  

          對(duì)應(yīng)結(jié)構(gòu)是:

          1. xmlns:你自己定義的名稱="http://schemas.android.com/apk/res/你程序的package包名"    (我這是com.example.declare_styleable)  

          包名是配置文件中   package="com.example.declare_styleable" 這樣格式的

          之后在布局中自定義的類中設(shè)相關(guān)屬性:

          你自己定義的名稱:你設(shè)的屬性 ="屬性值";


          3.最后在自定義控件的構(gòu)造方法中獲取你配置的屬性值:

          1. public class PersonView extends TextView {  
          2.     public PersonView(Context context) {  
          3.         super(context);  
          4.         // TODO Auto-generated constructor stub  
          5.     }  
          6.   
          7.     public PersonView(Context context, AttributeSet attrs, int defStyle) {  
          8.         super(context, attrs, defStyle);  
          9.         // TODO Auto-generated constructor stub  
          10.     }  
          11.   
          12.     public PersonView(Context context, AttributeSet attrs) {  
          13.         super(context, attrs);  
          14.         // TODO Auto-generated constructor stub  
          15.         TypedArray tArray = context.obtainStyledAttributes(attrs,R.styleable.PersonAttr);//獲取配置屬性  
          16.         String name = tArray.getString(R.styleable.PersonAttr_name);<span style="font-family: Arial, Helvetica, sans-serif;">//得到屬性name</span>  
          17.         int age = tArray.getInt(R.styleable.PersonAttr_age, 15);  
          18.         Boolean adult = tArray.getBoolean(R.styleable.PersonAttr_adult, false);  
          19.         String str_adult = getAdultStatus(adult);  
          20.         int weight = tArray.getInt(R.styleable.PersonAttr_weight, 1);// 默認(rèn)是中等身材,屬性為:1  
          21.         String str_weight = getWeightStatus(weight);//獲得肥胖屬性  
          22.         float textSize = tArray.getDimension(R.styleable.PersonAttr_textSize,R.dimen.default_text_size);// 如果你設(shè)置為DP等單位,會(huì)做像素轉(zhuǎn)換  
          23.         tArray.recycle();//回收資源  
          24. //      setTextSize(textSize);//設(shè)置字體大小  
          25.         setText("姓名:" + name + "\n" + "年齡:" + age + "\n" + "是否成年:" + str_adult  
          26.                 + "\n" + "體形:" + str_weight);//給自定義的控件賦值  
          27.     }  
          28.       
          29.     /** 根據(jù)傳入的值判斷是否成年 */  
          30.     public String getAdultStatus(Boolean adult ){  
          31.         String str_adult = "未成年";  
          32.         if (adult) {  
          33.             str_adult = "成年";  
          34.         }  
          35.         return str_adult;  
          36.     }  
          37.       
          38.     /** 根據(jù)傳入的值判斷肥胖狀態(tài) */  
          39.     public String getWeightStatus(int weight){  
          40.         String str_weight = "中等";  
          41.         switch (weight) {  
          42.         case 0:  
          43.             str_weight = "瘦";  
          44.             break;  
          45.         case 1:  
          46.             str_weight = "中等";  
          47.             break;  
          48.         case 2:  
          49.             str_weight = "肥胖";  
          50.             break;  
          51.         default:  
          52.             break;  
          53.         }  
          54.         return str_weight;  
          55.     }  
          56. }  
          運(yùn)行后就是:



          這樣,以后我們就可以根據(jù)這個(gè)方法,去自定義控件并自定義配置屬性了,大大提高了自定義布局的使用效率。


          對(duì)應(yīng)的源碼下載地址:下載地址

          posted on 2014-12-16 12:43 Eric_jiang 閱讀(594) 評(píng)論(0)  編輯  收藏 所屬分類: Android
          主站蜘蛛池模板: 山丹县| 石嘴山市| 舟曲县| 平泉县| 凉山| 定西市| 固阳县| 台中市| 绥中县| 新津县| 伊吾县| 阿拉尔市| 根河市| 四子王旗| 建阳市| 玉环县| 辉县市| 彭泽县| 汾西县| 乌兰县| 福建省| 花垣县| 鱼台县| 盐城市| 台中县| 孝昌县| 建昌县| 巴南区| 新乡县| 淳化县| 永兴县| 南昌县| 封丘县| 弥勒县| 乌鲁木齐市| 贡山| 高淳县| 禹州市| 贵港市| 武定县| 嘉黎县|