標籤:
一、建立一個控制項類間接或者直接繼承View類
二、建立自訂的樣式屬性放在attr.xml檔案裡面,如
<?xml version="1.0" encoding="utf-8"?><resources> <attr name="titleText" format="string" /> <attr name="titleTextColor" format="color" /> <attr name="titleTextSize" format="dimension" /> <declare-styleable name="CustomTitleView"> <attr name="titleText" /> <attr name="titleTextColor" /> <attr name="titleTextSize" /> </declare-styleable></resources>
三、在控制項類裡面實現相關的邏輯
1、重載三個構造方法
public CustomTitleView(Context context, AttributeSet attrs)
public CustomTitleView(Context context)
public CustomTitleView(Context context, AttributeSet attrs, int defStyle)
2、在構造方面裡面擷取樣式屬性,類似WP裡面的控制項樣式
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);
在構造方面裡面可以做一些初始化的操作
3、重載onMeasure方法來測量控制項,跟wp的邏輯一模一樣
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
4、重載onDraw方法繪製螢幕
protected void onDraw(Canvas canvas)
canvas是控制項的畫布對象,在這裡你可以在canvas上面繪製或者添加你需要在控制項上面顯示的內容或者其他的控制項。
四、在layout上面使用
1、使用屬性的時候需要增加空間的引用
xmlns:custom="http://schemas.android.com/apk/res/com.example.asdlon.customviewdemo"
2、添加控制項
<com.example.asdlon.customviewdemo.CustomTitleView android:layout_width="wrap_content" android:layout_height="wrap_content" custom:titleText="3712" android:padding="10dp" custom:titleTextColor="#ff0000" android:layout_centerInParent="true" custom:titleTextSize="40sp" />
import java.util.HashSet;import java.util.Random;import java.util.Set;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.util.AttributeSet;import android.util.TypedValue;import android.view.View;public class CustomTitleView extends View{ /** * 文本 */ private String mTitleText; /** * 文本的顏色 */ private int mTitleTextColor; /** * 文本的大小 */ private int mTitleTextSize; /** * 繪製時控制文本繪製的範圍 */ private Rect mBound; private Paint mPaint; public CustomTitleView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CustomTitleView(Context context) { this(context, null); } /** * 獲得我自訂的樣式屬性 * * @param context * @param attrs * @param defStyle */ public CustomTitleView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); /** * 獲得我們所定義的自訂樣式屬性 */ TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.CustomTitleView_titleText: mTitleText = a.getString(attr); break; case R.styleable.CustomTitleView_titleTextColor: // 預設顏色設定為黑色 mTitleTextColor = a.getColor(attr, Color.BLACK); break; case R.styleable.CustomTitleView_titleTextSize: // 預設設定為16sp,TypeValue也可以把sp轉化為px mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics())); break; } } a.recycle(); /** * 獲得繪製文本的寬和高 */ mPaint = new Paint(); mPaint.setTextSize(mTitleTextSize); // mPaint.setColor(mTitleTextColor); mBound = new Rect(); mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound); this.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mTitleText = randomText(); postInvalidate(); } }); } private String randomText() { Random random = new Random(); Set<Integer> set = new HashSet<Integer>(); while (set.size() < 4) { int randomInt = random.nextInt(10); set.add(randomInt); } StringBuffer sb = new StringBuffer(); for (Integer i : set) { sb.append("" + i); } return sb.toString(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = 0; int height = 0; /** * 設定寬度 */ int specMode = MeasureSpec.getMode(widthMeasureSpec); int specSize = MeasureSpec.getSize(widthMeasureSpec); switch (specMode) { case MeasureSpec.EXACTLY:// 明確指定了 width = getPaddingLeft() + getPaddingRight() + specSize; break; case MeasureSpec.AT_MOST:// 一般為WARP_CONTENT width = getPaddingLeft() + getPaddingRight() + mBound.width(); break; } /** * 設定高度 */ specMode = MeasureSpec.getMode(heightMeasureSpec); specSize = MeasureSpec.getSize(heightMeasureSpec); switch (specMode) { case MeasureSpec.EXACTLY:// 明確指定了 height = getPaddingTop() + getPaddingBottom() + specSize; break; case MeasureSpec.AT_MOST:// 一般為WARP_CONTENT height = getPaddingTop() + getPaddingBottom() + mBound.height(); break; } setMeasuredDimension(width, height); } @Override protected void onDraw(Canvas canvas) { mPaint.setColor(Color.YELLOW); canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint); mPaint.setColor(mTitleTextColor); canvas.drawText(mTitleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint); }}
參考:http://blog.csdn.net/lmj623565791/article/details/24252901
Android 自訂View(自訂控制項)