http://orgcent.com/android-custom-view-draw-mechanism/html
@Override android
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { canvas
int width = MeasureSpec.getSize(widthMeasureSpec); //獲取ViewGroup寬度 ide
int height = MeasureSpec.getSize(heightMeasureSpec); //獲取ViewGroup高度 函數
setMeasuredDimension(width, height); //設置ViewGroup的寬高 url
int childCount = getChildCount(); //得到子View的個數,下面遍歷這些子View設置寬高 spa
for (int i = 0; i < childCount; i++) { .net
View child = getChildAt(i); code
child.measure(viewWidth, viewHeight); //設置子View寬高 orm
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int mTotalHeight = 0;
// 固然,也是遍歷子View,每一個都要告訴ViewGroup
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
// 獲取在onMeasure中計算的視圖尺寸
int measureHeight = childView.getMeasuredHeight();
int measuredWidth = childView.getMeasuredWidth();
childView.layout(left, mTotalHeight, measuredWidth, mTotalHeight + measureHeight);
mTotalHeight += measureHeight;
}
}
// 繪製前景圖 ,新畫上去的圖片能夠理解爲前景,就是src。
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
// 繪製背景圖 ,canvas原有的圖片能夠理解爲背景,就是dst;
paint2 = new Paint();
paint2.setXfermode(null);
Rect參數的意思表明的是矩形的左上角的座標(left、top)和右下角的座標(right、bottom)
由兩點的位置肯定了矩形的高和寬
高:bottom-top
寬:right-left
public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
oval :指定圓弧的外輪廓矩形區域。
startAngle: 圓弧起始角度,單位爲度。
sweepAngle: 圓弧掃過的角度,順時針方向,單位爲度。
useCenter: 若是爲True時,在繪製圓弧時將圓心包括在內,一般用來繪製扇形。
paint: 繪製圓弧的畫板屬性,如顏色,是否填充等。
當recycle被調用後,這就說明這個對象從如今能夠被重用了。
原文地址:http://www.cnblogs.com/kissazi2/p/4049982.html
原理說明:http://www.haodaima.net/art/2603825 講的好!
最複雜的地方就是畫刻度了,這裏要先複習一下數學中的三角函數:
刻度的起始位置就是圓框上的一個點,第一步就是要知道這個點的座標。上圖中:
sinθ = AC / AO
cosθ = OC / AO
其中AO即爲圓半徑,而θ的值則根據刻度而定。0是π/2,3是0,6是3π/2,9是π:
由此可獲得刻度起始點的位置爲:
x = 圓點橫座標 + AO * cosθ
y = 圓點縱座標 + AO * sinθ
同理可算出刻度結束點的位置爲(結束點至關於在一個半徑爲圓框半徑-刻度長度的圓上):
x = 圓點橫座標 + (AO - 刻度長度) * cosθ
y = 圓點縱座標 + (AO - 刻度長度) * sinθ
因而,這程序能夠寫了:
for (var i = 0, angle = 0, tmp, len; i < 60; i++) {
bgCtx.beginPath();
// 突出顯示能被5除盡的刻度
if (0 === i % 5) {
bgCtx.lineWidth = 5;
len = 12;
bgCtx.strokeStyle = '#000';
} else {
bgCtx.lineWidth = 2;
len = 6;
bgCtx.strokeStyle = '#999';
}
tmp = radius - borderWidth / 2; // 由於圓有邊框,因此要減去邊框寬度
bgCtx.moveTo(
dot.x + tmp * Math.cos(angle),
dot.y + tmp * Math.sin(angle)
);
tmp -= len;
bgCtx.lineTo(dot.x + tmp * Math.cos(angle), dot.y + tmp * Math.sin(angle));
bgCtx.stroke();
bgCtx.closePath();
angle += Math.PI / 30; // 每次遞增1/30π
}
正玄定理餘玄定理回顧:http://baike.baidu.com/link?url=a2JC6gyPPQh2ZOQ6UJjrcpvNeaG6mPeXLWVoix6u7E3FhOG4NynGdTyl61VosvO4
該方法的聲明爲:
void android.graphics.Path.arcTo(RectF oval, float startAngle, float sweepAngle);
該方法是畫一個弧線的路徑.
第一個參數是一個RectF類型.這個參數是幹嗎的呢?
先說一下,這個弧線是怎麼來的?是先畫一個橢圓,而後再在這個橢圓上面截取一部分部形。這個圖形天然就是一個弧線了。那麼這個橢圓是怎麼肯定的呢?這就是這個rectF參數所起的做用了。
如圖所示:
給出這個矩形後,系統就能夠算出這個矩形的中心,而後以這個矩開的中心畫一個橢圓。
獲得這個橢圓後,而後就是截取一部分線了,就獲得最終的弧線。這一部分是怎麼截取的呢?
這就是後面兩個參數共同來表達的。
startAngle這個參數說的是開始的角度。這個好理解,但哪裏是0度線呢,又是向哪一個方向旋轉是正角度數呢?下面由圖形來展現:
圖上所示的紅線就是0度線。
startAngle是開始度數,那sweepAngle是指的什麼呢?
sweepAngle指的是旋轉的度數,也就是以startAngle開始,旋轉多少度,若是sweepAngle是正數,那麼就是按順時針方向旋轉,若是是負數就是按逆時針方向旋轉。
若是示例:startAngle = 0; sweepAngle=90時:
紅色部分的弧線就是最終的弧線...