天天看點

自定義Android View屬性

自定義MyTextView

如何自定義一個簡單的View.

第一步在res/Value檔案夾下建立新的attr.xml檔案;

<?xml version="1.0" encoding="UTF-8"?>

<resources>

<attr format="string" name="text"/>

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

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

<declare-styleable name="MyTextView">

<attr name="text"/>

<attr name="textsize"/>

<attr name="backGround"/>

</declare-styleable>

</resources>

其中我自定義了 text textsize backgroud 三個屬性 ,format 的作用為定義屬性值的類型有String color blooean float,intager,dimension等幾種類型

declare-styleable 的作用: styleale 的出現系統可以為我們完成很多常量(int[]數組,下标常量)等的編寫,簡化我們的開發工作

第二步構造函數繼承View 重寫OnMeasure();OnDrow();方法;

//在上面構造方法裡面我們獲得我們自定義的樣式;

public class MyTextView extends View {

// 定以屬性

private String mText;

private int mBackground;

private int mTextSize;

private Rect mBunds;

private Paint mPaint;

public MyTextView(Context context) {

this(context, null);

}

public MyTextView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

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

super(context, attrs, defStyleAttr);

// TODO Auto-generated constructor stub

TypedArray a = context.getTheme().obtainStyledAttributes(attrs, com.example.asasas.R.styleable.MyTextView,

defStyleAttr, 0);

for (int i = 0; i < a.getIndexCount(); i++) {

int array = a.getIndex(i);

switch (array) {

case R.styleable.MyTextView_text:

mText = a.getString(array);

break;

case R.styleable.MyTextView_textsize:

mTextSize = a.getDimensionPixelSize(array, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,

16, getResources().getDisplayMetrics()));

break;

sp與dp的互換

case R.styleable.MyTextView_backGround:

mBackground = a.getColor(array, Color.BLACK);

break;

}

}

a.recycle();

mPaint = new Paint();

mPaint.setTextSize(mTextSize);

mBunds = new Rect();

mPaint.getTextBounds(mText, 0, mText.length(), mBunds);

}

TypeArray的作用:

TypedArray其實是用來簡化我們的工作的,如果布局中的屬性的值是引用類型(比如:@dimen/dp100),如果使用AttributeSet去獲得最終的像素值,那麼需要第一步拿到id,第二步再去解析id。而TypedArray正是幫我們簡化了這個過程。

AttributeSet的作用

AttributeSet中儲存的是該View聲明的所有的屬性以通過它去擷取(自定義的)屬性

重寫OnMeasure()獲得大小的大小

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// TODO Auto-generated method stub

int width;

int height;

int widthMode = MeasureSpec.getMode(widthMeasureSpec);

int widthSize = MeasureSpec.getSize(widthMeasureSpec);

if (widthMode == MeasureSpec.EXACTLY) {

width = getPaddingLeft() + getPaddingRight() + widthSize;

} else {

mPaint.setTextSize(mTextSize);

mPaint.getTextBounds(mText, 0, mText.length(), mBunds);

int desired = (int) (getPaddingLeft() + mBunds.width() + getPaddingRight());

width = desired;

}

int heightMode = MeasureSpec.getMode(heightMeasureSpec);

int heightSize = MeasureSpec.getSize(heightMeasureSpec);

if (heightMode == MeasureSpec.EXACTLY) {

height = getPaddingTop() + getPaddingBottom() + heightSize;

} else {

mPaint.setTextSize(mTextSize);

mPaint.getTextBounds(mText, 0, mText.length(), mBunds);

int desired = (int) (getPaddingTop() + mBunds.height() + getPaddingBottom());

height = desired;

}

setMeasuredDimension(width, height);

}

重寫OnDrow();方法畫出控件

@Override

protected void onDraw(Canvas canvas) {

// TODO Auto-generated method stub

mPaint.setColor(mBackground);

canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);

mPaint = new Paint();

canvas.drawText(mText, getWidth() / 2 - mBunds.width() / 2, getHeight() / 2 + mBunds.height() / 2, mPaint);

}

第三步:在布局檔案中使用自定義的控件.

<com.example.asasas.View.MyTextView

 android:layout_height="43dp"

 android:layout_width="32dp" app:textsize="26sp"

 app:text="測試1" 

app:backGround="#578" 

android:padding="10dp"/>

<com.example.asasas.View.MyTextView

 android:layout_height="wrap_content" 

android:layout_width="wrap_content" 

app:textsize="45dp" app:text="測試2"

 app:backGround="#713"

 android:padding="15dp"

 android:layout_centerInParent="true"/>

更多詳情:http://blog.csdn.net/lmj623565791/article/details/24252901

.

繼續閱讀