屬性(Attribute)資源:屬於整個Android應用資源的一部分.其實就是網上一堆介紹怎麼給自定義View添加自己的屬性文章裏的attrs文件,此文件位於../res/values/目錄下
當別人通過XML文件配置的方式來創建你開發的自定義組件,並且還能動態設置你自定義組件的屬性時,這時候你就需要給你自己自定義的組件配上一個XML屬性資源文件來完成這項工作了.
其實也可以不配上一個XML屬性資源文件,也能完成如上的功能,這樣你的自定義組件顯得更乾脆一點,一個自定義組件就是一個類文件,不拖泥帶水的。但是這兩種方式是有區別的,具體看自己的需求來選擇了,以下爲兩種實現方式:
1:配合XML屬性資源文件的方式
第一步:attrs.xml文件
首先當然是要寫出自定義組件的類文件了,然後將這個類裏需要外界傳入值的屬性定義成一個屬性資源文件.
在工程裏的../res/values/目錄下創建一個attrs.xml文件,文件名並不是只能寫成這樣,這樣寫只有一個目的,別人一看就知道這個文件是屬性資源文件了,具體寫法如下:
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <attr name="test1" format="string" />
- <declare-styleable name="MyView">
- <attr name="textColor" format="color" />
- <attr name="textSize" format="dimension" />
- <attr name="text" format="string" />
- </declare-styleable>
- </resources>
attrs.xml解釋如下
- attr子元素:
- 定義具體的屬性,format表示這個屬性的值的類型,類型有以下幾種:
- 1.reference:參考指定Theme中資源ID,這個類型意思就是你傳的值可以是引用資源
- 2.string:字符串,如果你想別人既能直接寫值也可以用類似"@string/test"引用資源的方式,可以寫成format="string|reference"
- 3.Color:顏色
- 4.boolean:布爾值
- 5.dimension:尺寸值
- 6.float:浮點型
- 7.integer:整型
- 8.fraction:百分數
- 9.enum:枚舉 ,如果你提供的屬性只能讓別人選擇,不能隨便傳入,就可以寫成這樣
- <attr name="language">
- <enum name="china" value="1"/>
- <enum name="English" value="2"/>
- </attr>
- 10.flag:位或運算
- declare-styleable子元素:
- 定義一個styleable對象,每個styleable對象就是一組attr屬性的集合 注意:這裏的name屬性並不是一定要和自定義類名相同,只是爲了好區分對應類的屬性而已
- 注意:上面的屬性資源文件定義了該屬性之後,至於到底是哪個自定義View組件中來使用該屬性,該屬性到底能發揮什麼作用, 就不歸該屬性資源文件管了,也就是說這個屬性資源文件是個公共的,大家都可以用,但是爲了方便管理,一般都是一個自定義View裏的屬性寫成一個declare-styleable集合.屬性資源所定義的屬性到底可以返回什麼作用,取決於自定義組件的代碼實現
第二步:在自定義類裏引用attrs文件裏定義的屬性爲自己的屬性設置值
- package cn.com.androidtest.ui;
- import cn.com.androidtest.R;
- import android.content.Context;
- import android.content.res.TypedArray;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Paint.Style;
- import android.graphics.Rect;
- import android.util.AttributeSet;
- import android.view.View;
- public class MyView extends View
- {
- private Paint mPaint;
- private Context mContext;
- private static String mString;
- private String test;
- public MyView(Context context)
- {
- super(context);
- mPaint = new Paint();
- }
- public MyView(Context context,AttributeSet attrs)
- {
- super(context,attrs);
- mPaint = new Paint();
- /*這裏取得declare-styleable集合*/
- TypedArray typeArray = context.obtainStyledAttributes(attrs,R.styleable.MyView);
- /*這裏從集合裏取出相對應的屬性值,第二參數是如果使用者沒用配置該屬性時所用的默認值*/
- int textColor = typeArray.getColor(R.styleable.MyView_textColor,0XFFFFFFFF);
- float textSize = typeArray.getDimension(R.styleable.MyView_textSize, 36);
- mString = typeArray.getString(R.styleable.MyView_text);
- /*設置自己的類成員變量*/
- mPaint.setTextSize(textSize);
- mPaint.setColor(textColor);
- /*關閉資源*/
- typeArray.recycle();
- }
- @Override
- protected void onDraw(Canvas canvas)
- {
- super.onDraw(canvas);
- mPaint.setStyle(Style.FILL);
- canvas.drawRect(new Rect(10, 10, 90, 90), mPaint);
- mPaint.setColor(Color.BLUE);
- canvas.drawText(mString, 10, 110, mPaint);
- }
- }
第三步:使用自定義組件,並設置屬性
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:myandroid="http://schemas.android.com/apk/res/cn.com.androidtest"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"/>
- <cn.com.androidtest.ui.MyView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- myandroid:textColor="#ff0000"
- myandroid:textSize="20px"
- myandroid:text="http://wujiandong.iteye.com"/>
- </LinearLayout>
注意:java代碼裏那種取屬性值的方式,那麼在XML使用該組件的時候一定要爲該自定義組件設置一個命名空間[xmlns:myandroid="http://schemas.android.com/apk/res/cn.com.androidtest"],不然組件屬性設置不了
命名空間寫法:xmlns:空間名="http://schemas.android.com/apk/res/自定義組件所在包名"
寫包名時候也有個要注意的地方:
如果你的自定義View所在包類似如下兩圖,那麼包名只能寫成最頂層包[cn.com.androidtest],而不能是[cn.com.androidtest.ui]
第四步:終於完成了,看下效果圖
2:不需要配合XML資源文件的方式
基本與第一種方式相同,只是java代碼取屬性值的部分,和別人用你自義View時有點區別
java代碼寫法:
- /*資源ID號引用*/
- int resouceId = -1;
- /*取得資源ID號,第一個參數:命名空間名.第二個參數:xml文件裏設置的屬性名.第三個參數:默認值*/
- resouceId = attrs.getAttributeResourceValue(null, "textColor", 0);
- if (resouceId > 0)
- textColor = context.getResources().getColor(resouceId);
- resouceId = attrs.getAttributeResourceValue(null, "textColor", 0);
- if(resouceId > 0)
- mString = context.getResources().getText(resouceId, "http://wujiandong.iteye.com").toString();
XML中使用的時候,命名空間可以不要,屬性名就要自己對應好了,不然程序取不到,不像有XML資源文件配合的方式有個約束.絕對自由等於沒有自由~~
- <cn.com.androidtest.ui.MyView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- textColor="#ff0000"
- textSize="20px"
- text="http://wujiandong.iteye.com"/>