Android自定義組合控制元件之自定義屬性

我叫阿狸貓發表於2014-02-28

自定義組合控制元件:

1.就是將一大段定義樣式的程式碼通過用一個java類的全路徑作為標籤名就能代替使用。(相當於封裝程式碼)

2.有些效果的控制元件安卓系統不支援,所以要自己定義,所以有些特殊屬性也要自己定義了。




步驟一共三步:

1.建立一個類繼承View,覆寫對應的3個構造方法    如果沒有覆寫對應的構造方法會出NoSuchMethodException

/**
 * 自定義屬性:
 * 1.建立一個類繼承View,覆寫對應的3個構造方法    如果沒有覆寫對應的構造方法會出NoSuchMethodException
 * 2.在values目錄下建立attrs.xml,並在檔案裡宣告自定義屬性集合名稱,屬性名稱和型別
 * 3.在佈局檔案裡用自定義類的全路徑作為標籤名,建立自定義元件
 * 		1.在命名控制元件裡修改   xmlns:(自定義屬性字首名)    com.xxc.attribute表示包名,  其他固定
 * 			xmlns:xxc="http://schemas.android.com/apk/res/com.xxc.attribute"
 * 		2.在自定義元件中使用自定義屬性xxc:test_bitmap="@drawable/ic_launcher"
 * 4.在自定義View類裡對應的建構函式中,用context.obtainStyledAttributes()解析AttributeSet裡的簡單加工資料成物件
 * 然後就可以獲取具體資料了
 *
 */
public class MyView extends View {
	
	/**
 	 * 程式碼建立元件的時候執行 
	 */
	public MyView(Context context) {
		super(context);
	}
	

	/**
	 * 在佈局檔案中建立View物件的時候執行該方法 
	 * @param context 上下文物件
	 * @param attrs 解析xml對應的自定義元件,簡單進行資料處理
	 */
	public MyView(Context context, AttributeSet attrs) {
		super(context, attrs);
		/*
		 * 這種方法雖然簡便,但是不規範
		 * @2131034112  因為是引用了別的資原始檔裡的資料 所以這種方法只返回了id值  
		 */
		System.out.println(attrs.getAttributeValue("http://schemas.android.com/apk/res/com.xxc.attribute","test_msg"));
		//hehe
		System.out.println(attrs.getAttributeValue(null,"haha"));
		/*
		 * AttributeSet僅對XML的屬性進行了簡單處理
		 *  name--->layout_width
		 *	value--->-2
		 *	name--->layout_height
		 *	value--->-2
		 *	name--->test_msg
		 *	value--->@2131034112
		 *	name--->test_bitmap
		 *	value--->@2130837504
		 */
		for (int i = 0; i < attrs.getAttributeCount(); i++) {
			String name = attrs.getAttributeName(i);
			String value =  attrs.getAttributeValue(i);
			System.out.println("name--->"+name);
			System.out.println("value--->"+value);
		}
		System.out.println("-------------------------------------------------------------");
		//對簡單處理後的屬性集合進行深加工,返回的TypedArray可以遍歷獲取具體物件   引數一 AttributeSet  引數二  自定義屬性集合名
		TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyView);
		//這種方法不需要迴圈
		System.out.println("原先方法的id======================="+ta.getString(R.styleable.MyView_test_msg));
		int count = ta.getIndexCount();
		for (int i = 0; i < count; i++) {
			int index = ta.getIndex(i);
			switch (index) {
			case R.styleable.MyView_test_id:
				int id = ta.getInteger(index, -1);
				System.out.println("id---->"+id);
				break;
			case R.styleable.MyView_test_msg:
				String msg = ta.getString(index);
				System.out.println("msg---->"+msg);
				break;
			case R.styleable.MyView_test_bitmap:
				int resourceId = ta.getResourceId(index, -1);
				System.out.println("圖片id--->"+resourceId);
				break;
			}
		}
		
		ta.recycle();//釋放資源
	}
	
	public MyView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

}

2.在values目錄下建立attrs.xml,並在檔案裡宣告自定義屬性集合名稱,屬性名稱和型別

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- 宣告屬性集的名稱 -->
    <declare-styleable name="MyView">

        <!-- 宣告一個屬性name是test_id 型別為整數型別 -->
        <attr name="test_id" format="integer" />
        <!-- 宣告一個屬性name是test_msg 型別為字串型別 -->
        <attr name="test_msg" format="string" />
        <!-- 宣告一個屬性name是test_bitmap 型別為引用型別 -->
        <attr name="test_bitmap" format="reference" />
    </declare-styleable>

</resources>

3.在佈局檔案裡用自定義類的全路徑作為標籤名,建立自定義元件

                         1.在命名控制元件裡修改   xmlns:(自定義屬性字首名)    com.xxc.attribute表示包名  是清單檔案裡的包名,不是自定義類的包名(千萬別搞錯),  其他固定

                                  xmlns:xxc="http://schemas.android.com/apk/res/com.xxc.attribute"

                         2.在自定義元件中使用自定義屬性xxc:test_bitmap="@drawable/ic_launcher"

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:xxc="http://schemas.android.com/apk/res/com.xxc.attribute"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.xxc.attribute.MyView
        haha="hehe"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        xxc:test_bitmap="@drawable/ic_launcher"
        xxc:test_msg="@string/app_name" />

</RelativeLayout>

4.在自定義View類裡對應的建構函式中,用context.obtainStyledAttributes()解析AttributeSet裡的簡單加工資料成物件  然後就可以獲取具體資料了  參照第一步裡構造方法裡


相關文章