天天看點

自定義View(1)------------自定義屬性

先貼一個網址,這個大神畫的不錯  http://blog.csdn.net/wangchunlei123/article/details/50478913

自定義View的步驟:

1、建立一個自定義的View如:MyNoteView繼承View或者View的子類

寫構造方法:根據需要寫出構造函數

public MyNoteView(Context context)   通過java代碼寫布局    new 這個對象的時候會執行該方法

public MyNoteView(Context context, AttributeSet attrs)    使用xml檔案布局的時候使用  

參數說明:AttributeSet:引用資源的屬性集合

public MyTextView(Context context, AttributeSet attrs, int defStyleAttr)

也是在xml檔案中使用該方法 如果本類中 寫了該構造方法,則必須還要添加 上面第二個構造方法

參數說明:defStyleAttr 預設的一個屬性風格id

2、自定義屬性:在res\values檔案夾建立attrs.xml檔案

使用declare-styleable标簽聲明自定義View,聲明時anme的值必須與使用該屬性的View 名稱相同,如:

<declare-styleable name="MyTextView">
        <attr name="textColor" format="color|reference"></attr>
        <attr name="textSize" format="dimension"></attr>
        <attr name="text" format="string"></attr>
    </declare-styleable>
           

(1)定義每個屬性的 name,     name可以随便命名,但是最好見名知意

(2)   定義每個屬性的format(格式)  填寫格式類型可以多種       以   “|”  符号連結

format的類型

1、reference   參考某一資源 ,通常是@開頭,例如@+id/xxxx,@id/xxx

2、color          顔色值

3、boolean     布爾值

4、dimension 尺寸值(帶有機關的 sp/dp)

5、float           浮點型

6、integer 整形

7、string 字元串

8、fraction       百分比

9、enum 枚舉

10、flag 位或運算

(3)在xml檔案中使用自定義的屬性,

注意:

①自定義View的引用 必須是包名+類名(全路徑)

②根元素的中必須增加了一個額外的命名空間: xmlns:app="http://schemas.android.com/apk/res/com.phone.day28_customviewattr"      其中app表示      元素中使用以app開頭的屬性,

...../res/後表示完整的包名com.phone.day28_customviewattr    具體使用如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res/com.phone.day28_customviewattr"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <!-- 自定義View的引用 必須是包名+類名(全路徑) -->

    <com.phone.day28_customviewattr.MyTextView
        android:id="@+id/myTextView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        app:text="我是石頭裡蹦出來的"
        app:textColor="@android:color/holo_blue_light"
        app:textSize="24sp" />

</RelativeLayout>
           

③在java代碼中要使用自定義的屬性

在 自定義View 的構造方法中  通過TypedArray 将我們設定的值拿出來,賦予畫筆或畫布進行繪制

我們調用Context.obtainStyledAttributes方法獲得TypedArray的對象

在attrs.xml中定義的名稱,通過R.styleable來通路,按照attrs.xml中定義的屬性的類型,使用不同的get方法擷取指定屬性的值。

TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.MyTextView);
	color = array.getColor(R.styleable.MyTextView_textColor, Color.BLACK);
	text = array.getString(R.styleable.MyTextView_text);
	size = array.getDimension(R.styleable.MyTextView_textSize, 18);
           

完整擷取屬性代碼如下:

public MyTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		// 畫筆
		mPaint = new Paint();

		// 幫助我們将設定的屬性資源拿到這裡
		TypedArray array = context.obtainStyledAttributes(attrs,
				R.styleable.MyTextView);
		color = array.getColor(R.styleable.MyTextView_textColor, Color.BLACK);
		text = array.getString(R.styleable.MyTextView_text);
		size = array.getDimension(R.styleable.MyTextView_textSize, 18);

		
		mPaint.setColor(color);
		mPaint.setTextSize(size);
		// 回收
		array.recycle();
	}
           

(4)根據需要重寫以下方法;

①測量,計算目前view 的大小   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

②位置 1自身相對于 父布局的位置 2如果自身是ViewGroup 還有 childView 相對于自身的位置

protected void onLayout(boolean changed, int left, int top, int right,  int bottom)

③控制View在螢幕上的渲染效果,protected void onDraw(Canvas canvas)

④監聽手勢滑動public boolean onTouchEvent(MotionEvent event)

以下寫一個簡單的例子并貼出一個完整代碼:

自定義的一個View   MyTextView

package com.phone.day28_customviewattr;

import android.annotation.SuppressLint;
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.view.MotionEvent;
import android.view.View;

public class MyTextView extends View {

	Paint mPaint;

	int color;
	float size;
	String text = "";

	/**
	 * 
	 * 構造方法 一般隻使用第一個(new 的時候)和 第二個xml 檔案中
	 * 
	 * @param context
	 */
	// 在java代碼中 new 這個對象的時候會執行該方法
	public MyTextView(Context context) {
		super(context);
	}

	// 當在xml檔案中使用的時候會執行該方法
	// AttributeSet:引用資源的屬性集合
	@SuppressLint("Recycle")
	public MyTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		// 畫筆
		mPaint = new Paint();

		// 幫助我們将設定的屬性資源拿到這裡
		TypedArray array = context.obtainStyledAttributes(attrs,
				R.styleable.MyTextView);
		color = array.getColor(R.styleable.MyTextView_textColor, Color.BLACK);
		text = array.getString(R.styleable.MyTextView_text);
		size = array.getDimension(R.styleable.MyTextView_textSize, 18);

		
		mPaint.setColor(color);
		mPaint.setTextSize(size);
		// 回收
		array.recycle();
	}

	// //也是在xml檔案中使用該方法 如果本類中 寫了該構造方法,則必須還要添加 上面第二個構造方法
	// defStyleAttr 預設的一個屬性風格id
	public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
	}

	/**
	 * 測量,計算目前view 的大小
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}

	/**
	 * 位置 1自身相對于 父布局的位置 2如果自身是ViewGroup 還有 childView 相對于自身的位置
	 * 
	 */
	@Override
	protected void onLayout(boolean changed, int left, int top, int right,
			int bottom) {
		super.onLayout(changed, left, top, right, bottom);
	}

	/**
	 * 繪制 1 畫布 2 畫筆 3 内容
	 * 
	 */
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// 繪制  目前textView
		canvas.drawText(text, 100, 100, mPaint);
	}

	/**
	 * 監聽手勢滑動
	 */

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		return super.onTouchEvent(event);
	}

}
           

atrrs.xml檔案的代碼

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

    <declare-styleable name="MyTextView">
        <attr name="textColor" format="color|reference"></attr>
        <attr name="textSize" format="dimension"></attr>
        <attr name="text" format="string"></attr>
    </declare-styleable>
</resources>
           

使用自定義屬性的xml檔案activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res/com.phone.day28_customviewattr"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <!-- 自定義View的引用 必須是包名+類名(全路徑) -->

    <com.phone.day28_customviewattr.MyTextView
        android:id="@+id/myTextView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        app:text="我是石頭裡蹦出來的"
        app:textColor="@android:color/holo_blue_light"
        app:textSize="24sp" />

</RelativeLayout>
           

在自定義View中重寫相應的方法就可以了

關于自定義View 的其他知識會在之後寫出來

繼續閱讀