平時開發界面時,Android系統為我們提供了各種各樣的View元件,TextView、ImageView、Button、LinearLayout、ScrollView、ListView等等,這些也基本滿足了平時的開發要求。有時候開發也會遇到比較刁鑽的需求,自定義View多多少少就會用到。
徹底搞懂自定義View并不容易,因為牽扯到尺寸計算、Location(定位)、Canvas、矩陣計算等等,内容還是挺多的。記得剛入門Android時很快搞定了一個自定義View,後面才發現這還遠遠不夠。
1,首先要配置View的尺寸和位置
1)比如實作一個正方形的View,保持高度和寬度一緻
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
2)配置View在父View中的位置,使用onLayout
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
2,在繪制内容前,你要準備好畫筆
prPaint = new Paint();
//防鋸齒
prPaint.setAntiAlias(true);
//防抖動
prPaint.setDither(true);
prPaint.setStrokeCap(Paint.Cap.ROUND);
prPaint.setStyle(Paint.Style.STROKE);
prPaint.setStrokeWidth(PR_STROKE_WIDTH);
dot = new Path();
//指定順時針方向(CW)
dot.addCircle(0, 0, DOTTED_LINE_WIDTH / 2, Path.Direction.CW);
dotPaint = new Paint();
dotPaint.setAntiAlias(true);
dotPaint.setDither(true);
dotPaint.setStyle(Paint.Style.STROKE);
dotPaint.setColor(Color.WHITE);
innerCircle = new Paint();
innerCircle.setAntiAlias(true);
innerCircle.setDither(true);
innerCircle.setStyle(Paint.Style.STROKE);
innerCircle.setStrokeWidth(INNER_LINE);
innerCircle.setColor(themeColor);
effects_line = new DashPathEffect(new float[]{30, 10}, 1);
3,将内容通過畫布繪制出來
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
dotDrawRect.set(dotRect);
final float centerX = dotDrawRect.centerX();
final float centerY = dotDrawRect.centerY();
float radius = dotDrawRect.width() / 2;
initPathEffect();
dotPaint.setPathEffect(effects1);
canvas.drawCircle(centerX, centerY, radius, dotPaint);
radius = radius - DOTTED_LINE_PADDING;
dotPaint.setPathEffect(effects2);
canvas.drawCircle(centerX, centerY, radius, dotPaint);
radius = radius - DOTTED_LINE_PADDING;
dotPaint.setPathEffect(effects3);
canvas.drawCircle(centerX, centerY, radius, dotPaint);
radius = radius - DOTTED_LINE_PADDING;
dotPaint.setPathEffect(effects4);
canvas.drawCircle(centerX, centerY, radius, dotPaint);
radius = radius - DOTTED_LINE_PADDING;
innerCircle.setPathEffect(null);
innerCircle.setColor(Color.WHITE);
canvas.drawCircle(centerX, centerY, radius, innerCircle);
radius = (float) (radius - DOTTED_LINE_PADDING * 1.5);
innerCircle.setPathEffect(effects_line);
innerCircle.setColor(themeColor);
canvas.drawCircle(centerX, centerY, radius, innerCircle);
radius = radius - PR_STROKE_WIDTH / 2 - DOTTED_LINE_PADDING / 2;
if (powInterRadius == 0) {
powInterRadius = Math.pow(radius, 2);
}
//進度條繪制
dotDrawRect.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
prPaint.setColor(Color.GRAY);
canvas.drawArc(dotDrawRect, 120, 300, false, prPaint);
prPaint.setColor(Color.WHITE);
canvas.drawArc(dotDrawRect, 120, progress * 3, false, prPaint);
}
4,如果需要和使用者互動,還需要處理觸摸、點選這些事件(以後再仔細分析)
源碼:http://git.oschina.net/hanbingsheshou/SimpleDraw