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时:
红色部分的弧线就是最终的弧线...