1. 程式人生 > >自定義View自定義屬性

自定義View自定義屬性

在Android開發中常常需要自定義View,在自定義View後,常常需要一些特別的屬性,這裡一併講解如何自定義屬性。


1.自定義一個View類:MyNewElement.java


package com.ixgsoft.space;


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


/**
 * @Description: 
 */
public class NewMyElement extends View {


	
	private String TAG = "NewMyElement";
	private String text;
	
	public NewMyElement(Context context) {
		super(context);
		
	}
	public NewMyElement(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(attrs);




	}
	public NewMyElement(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(attrs);
	}


	public void init(AttributeSet attrs){
		
		TypedArray t = getContext().obtainStyledAttributes(attrs,R.styleable.NewMyElement);
		
		String textValue = t.getString(R.styleable.NewMyElement_textValue);
		float textSize = t.getDimension(R.styleable.NewMyElement_textSize, 36);
		int textColor = t.getColor(R.styleable.NewMyElement_textColor, 0xff000000);
	}
	




	
	


}




經過以上編碼,就成功的建立一個自己的View類了。如果要把這個View類放到layout檔案中,那麼應該這樣寫:


<?xml version="1.0" encoding="utf-8"?>
<LineanLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:my="http://schemas.android.com/apk/res/com.ixgsoft.space"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    
	<com.ixgsoft.space.NewMyElement
        my:textValue="草了1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
	<com.ixgsoft.space.NewMyElement 
      	my:textValue="草了2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />


</LineanLayout> 


在LinearLayout中,我定義了兩個NewMyElement元素,注意,自定義的View類,在Layout佈局檔案中必須使用完全包名,我這裡使用的是com.ixgsoft.space.NewMyElement。


2.建立自定義屬性


在Android中要增加自定義屬性,需要依靠attrs.xml檔案。這裡指定的自定義屬性,是在layout佈局檔案中使用的不是以android開頭的屬性,例如my:textValue。
首先,我們需要在/res/values目錄下新建一個名為 attrs.xml的檔案。


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="NewMyElement">
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
        <attr name="textValue" format="string" />
    </declare-styleable>
</resources>


這是一個android的resource檔案,其中有一個域,名為 declare-styleable(宣告屬性)。這個域的有一個name屬性為NewMyElement,這裡很重要,這個name屬性其實就是這個屬性的在R類中的id。在這裡域內部有3個attr域,他們都擁有兩個屬性,一個是name,代表這個屬性的名字以及在layout佈局檔案中的呼叫名。format代表著這個屬性的型別。這個屬性怎麼看呢?這裡教大家一個方法。
在layout佈局檔案中,使用eclipse的提示功能(Alt+/),可以看到所有屬性,這個時候按方向鍵,能夠切換焦點,同時右部的提示也在變換。每一個android預設的屬性,在提示的最後都有一個以[]包含的單詞,這個就是這個屬性的型別。 


目前已知的屬性有這些:
reference      資源型別,通常是@開頭,例如@+id/xxxx,@id/xxxxx
string             字串型別,通常是文字資訊
dimension   浮點型別,通常是尺寸度量,單位有很多px,dp,sp,dip等
color             顏色型別,通常是顏色16進位制程式碼,支援ARGB。
boolean       布林型別,true和false
enum           列舉型別,通常是代表這個屬性提供了幾種值來進行選擇,並且只能選擇這幾種中的一個
flag             與enum基本沒有區別。
integer         整數型別,通常是整數


建立完attrs.xml檔案,現在我們需要把這個屬性用到layout檔案中。


<?xml version="1.0" encoding="utf-8"?>
<LineanLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:my="http://schemas.android.com/apk/res/com.ixgsoft.space"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    
	<com.ixgsoft.space.NewMyElement
        my:textValue="草了1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
	<com.ixgsoft.space.NewMyElement 
      	my:textValue="草了2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</LineanLayout> 



以上程式碼中,在根元素的中增加了一個額外的名稱空間,xmlns:my="
http://schemas.android.com/apk/res/com.ixgsoft.space
"
最後的com.ixgsoft.space需要更改為你自己的包名。
做好之後,就可以在元素中使用以my開頭的屬性了,當然這裡是沒有Eclipse提示的,只能自己對照著寫。



3.在程式碼中呼叫自定義屬性

回到我們的View類MyNewElement。


package com.ixgsoft.space;


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


/**
 * @Description: 
 */
public class NewMyElement extends View {


	
	private String TAG = "NewMyElement";
	private String text;
	
	public NewMyElement(Context context) {
		super(context);
		
	}
	public NewMyElement(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(attrs);




	}
	public NewMyElement(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(attrs);
	}


	public void init(AttributeSet attrs){
		
		TypedArray t = getContext().obtainStyledAttributes(attrs,R.styleable.NewMyElement);
		
		String textValue = t.getString(R.styleable.NewMyElement_textValue);
		float textSize = t.getDimension(R.styleable.NewMyElement_textSize, 36);
		int textColor = t.getColor(R.styleable.NewMyElement_textColor, 0xff000000);
	}
	


}


在init方法中,接收了一個AttributeSet 物件,然後使用getContext方法得到當前Context,呼叫Context.obtainStyledAttributes方法,傳入AttributeSet 和R.styleable.NewMyElement,這裡的R.styleable.NewMyElement,就是我們在attrs.xml中定義的名稱,通過R.styleable來訪問。
方法返回一個 typedArray物件。按照attrs,xml中定義的屬性的型別,使用不同的get方法獲取指定屬性的值。看一看就懂了。