重寫View來實現全新的控制項

重寫View來實現全新的控制項

來自專欄 android之路

需要創建兩個文件

attrs_MyArcScaleMap.xml文件定義新控制項的xml屬性,代碼如下:

<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="MyArcScaleMap"> <attr name="myArcScaleMap_titleText" format="string"/> <attr name="myArcScaleMap_titleTextColor" format="color"/> <attr name="myArcScaleMap_titleTextSize" format="dimension"/> </declare-styleable></resources>

MyArcScaleMap.java文件包括如下內容:

構造方法:獲取自定義的屬性集(attrs.xml),創建TypedArray類來獲取屬性集,獲取完屬性集後需要調 用recycle()方法來避免重新創建的時候的錯誤;

畫筆初始化方法initXxx():初始化畫筆參數;

重載onDraw()方法:定義新控制項的畫布;

重載onMeasure()方法:獲取並設置新控制項的寬 高;

全部代碼如下:

package com.example.administrator.customwidget;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.view.View;public class MyArcScaleMap extends View { private int mMeasureHeight; private int mMeasureWidth; private String mArcScaleMapTitleText; private int mArcScaleMapTitleTextColor; private float mArcScaleMapTitleTextSize; private Paint mCirclePaint,mArcPaint,mTextPaint; private float mCircleXY; private float mRadius; //定義圓弧半徑 private RectF mArcRectF; float mSweepAngle = 0; private float mSweepValue = -60; //構造方法 public MyArcScaleMap(Context context){ super(context); } public MyArcScaleMap(Context context, AttributeSet attrs,int defStyleAttr){ super(context,attrs,defStyleAttr); } /** * MyArcScaleMap 構造方法 * @param context 上下文 參數 * @param attrs xml參數 */ public MyArcScaleMap(Context context, AttributeSet attrs){ super(context,attrs); TypedArray ta = context.obtainStyledAttributes( attrs,R.styleable.MyArcScaleMap); mArcScaleMapTitleText = ta.getString(R.styleable.MyArcScaleMap_myArcScaleMap_titleText); mArcScaleMapTitleTextColor = ta.getColor(R.styleable.MyArcScaleMap_myArcScaleMap_titleTextColor, 0); mArcScaleMapTitleTextSize =ta.getDimension(R.styleable.MyArcScaleMap_myArcScaleMap_titleTextSize,40); ta.recycle(); } /** * 重載onDraw方法,重定義畫布 * @param canvas 控制項畫布參數 * canvas.drawCircle 畫圓 * canvas.drawArc 畫圓弧 * canvas.drawText 寫字 */ @Override protected void onDraw(Canvas canvas){ super.onDraw(canvas); this.initMyArcScaleMap(); //繪製圓 canvas.drawCircle(mCircleXY,mCircleXY,mRadius,mCirclePaint); //繪製圓弧 canvas.drawArc(mArcRectF,0,mSweepAngle,false,mArcPaint); //繪製TEXT canvas.drawText(mArcScaleMapTitleText,0,mArcScaleMapTitleText.length(), mCircleXY,mCircleXY + (mArcScaleMapTitleTextSize/4),mTextPaint); } /** * 控制項大小測量 * @param widthMeasureSpec 控制項寬 * @param heightMeasureSpec 控制項高 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ mMeasureWidth = MeasureSpec.getSize(widthMeasureSpec); mMeasureHeight = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(mMeasureWidth,mMeasureHeight); } /** * initMyArcScaleMap() 初始化方法 * 初始化mCirclePaint mArcPaint mTextPaint等畫筆參數 */ public void initMyArcScaleMap(){ float length = 0; if(mMeasureHeight >= mMeasureWidth){ length = mMeasureWidth; }else { length =mMeasureHeight; } mCircleXY = length/2; mRadius = (float)(length*0.5)/2; mCirclePaint = new Paint(); mCirclePaint.setAntiAlias(true); mCirclePaint.setColor(getResources().getColor(android.R.color.holo_blue_bright)); mArcRectF = new RectF( (float) (length * 0.1), (float) (length * 0.1), (float) (length * 0.9), (float) (length * 0.9)); mSweepAngle = (mSweepValue / 100f) * 360f; mArcPaint = new Paint(); mArcPaint.setAntiAlias(true); mArcPaint.setColor(getResources().getColor(android.R.color.holo_blue_bright)); mArcPaint.setStrokeWidth((float) (length * 0.1)); mArcPaint.setStyle(Paint.Style.STROKE); mTextPaint = new Paint(); mTextPaint.setTextSize(mArcScaleMapTitleTextSize); mTextPaint.setColor(mArcScaleMapTitleTextColor); mTextPaint.setTextAlign(Paint.Align.CENTER); this.invalidate(); }}

推薦閱讀:

舞檯燈光使用之黃金三法則
品彥KTV設計會所案例賞析 享受離塵不離城的悠然
45㎡大開間客卧彈性分割值得借鑒!無主燈照明也很溫馨!
Font Awesome——奇妙字體
現場 |《2018設計和人工智慧報告》:全程回顧

TAG:iOS開發 | 設計 | Android開發 |