赞
踩
我们知道,onDraw()中,是进行绘制的地方。Canvas 和 Paint 就像我们平时画画所需要用的画笔和画纸,Paint 是画笔,我们可以设置画笔的颜色,画笔的线条的宽、透明,是否毛边等等,Canvas 是画布,比如可以提供不同颜色的画布,可以在画布上用笔画出矩形、圆形、弧线、三角形、图片、文字等等。
public class DrawView extends View {
Paint mPaint = new Paint();
public DrawView(Context context) {
this(context, null);
}
public DrawView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
mPaint.setAntiAlias(true);
//设置画笔宽度
mPaint.setStrokeWidth(5);
//设置画笔颜色
mPaint.setColor(Color.GRAY);
//设置画笔样式
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLUE);
canvas.drawCircle(300,300,100,paint);
}
}
这样,整个view的背景都是蓝色,在其上面画了一个圆,圆心距离其父容器的左上角距离x轴和y轴都是300px,圆的半径为100px。这只是一个例子,在 Canvas 中,例子很多
1) drawArc():绘制圆弧;
2) drawBitmap():绘制Bitmap图像;
3) drawCircle():绘制圆圈;
4) drawLine():绘制线条;
5) drawOval():绘制椭圆;
6) drawPath():绘制Path路径;
7) drawPicture():绘制Picture图片;
8) drawRect():绘制矩形;
9) drawRoundRect():绘制圆角矩形;
10) drawText():绘制文本;
11) drawVertices():绘制顶点。
这上面的都简单,参考着api就可以使用了。
这里提一下drawText的绘制,这个是绘制文案的,我们可以横着绘制文字、竖着绘制,还可以沿着圆绘制,这个api里也有说明,现在说一下横着绘制文案时,文字的高度问题,
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//标准线,先绘制一条线出来,等会你就会发现一个非常不可思议的事情
canvas.drawLine(100,100,1000,100,mPaint);
canvas.drawText("gaoxiaowomenshirenzhende....”,200,100,mPaint);
}
按理来说,文字应该在横线下面,紧贴着横线,但事实是,像abc这样的字母是在横线的上面,但像g这样的字母,g的下面已经突破横线了,这是怎么回事呢?这就是四线格与基线了。
drawText() 函数是绘制文本最常用的方法,开始以为(x,y) 就是要绘制的文字的左上角的坐标,其实不是,我们传进去的(x,y)其中的 y 表示的是上图中基线的位置,x也不是文案开始的位置。 paint.setTextAlign(Paint.Align.XXX); 这个函数是用来设置文字的对齐方式的,它的 取值有三个,左对齐(Panit.Align.LEFT)、居中对齐(Paint.Align.CENTER)和 右对齐(Paint.Align.RIGHT )。 当为左对齐时,x 指代的就是文案要绘制的 X 轴的坐标,(x,y)就是要绘制的文本的起始位置;居中对齐时,x 指代的是一个相对距离,是文案会以x为中点,x为文案的居中点;右对齐也同理,x 指的是文案的结尾处的位置的坐标。Y轴的值为基准线,基本可以理解为是文案文字底部所在的坐标,细扣的话,还有 ascent 线、 descent 线、top 线、bottom 线,我们平时一般用不到这么细致。
Canvas还有其他几个稍微不同的方法
1) canvas.save():把当前绘制的图像保存起来,让后续的操作相当于是在一个新图层上绘制;
2) canvas.restore():把当前画布调整到上一个save()之前的状态;
3) canvas.translate(dx, dy):把当前画布的原点移到(dx, dy)点,后续操作都以(dx, dy)点作为参照;
4) canvas.scale(x, y):将当前画布在水平方向上缩放x倍,竖直方向上缩放y倍;
5) canvas.rotate(angle):将当前画布顺时针旋转angle度。
先说 3) translate(dx, dy),这个意思是画布的原点位移,画布的原点默认是左上角,
Paint paint = new Paint();
paint.setColor(Color.YELLOW);
canvas.drawRect(new Rect(0, 0, 200, 200), paint);
意思是从左上角开始,画一个黄颜色的矩形,宽为200,高为200;如果我们使用了translate(dx, dy),那么
Paint paint = new Paint();
canvas.translate(200, 200);
paint.setColor(Color.YELLOW);
canvas.drawRect(new Rect(0, 0, 200, 200), paint);
这个矩形不变,但是往右和往下都位移了200,也就是说原先左上角顶点坐标由(0,0)变为(200,200),后续再画其他的图形,顶点也是以(200,200)为坐标,而非是原始的(0,0)坐标,除非执行canvas.translate(-200, -200); 这样才会回到原点(0,0)。
先讲3) ,然后再讲 1)和2) 就比较好理解了。save() 和 restore() 是成对出现的,restore()不能比save()调用的次数多。还是上面的例子,
Paint paint = new Paint();
canvas.translate(200, 200);
paint.setColor(Color.YELLOW);
canvas.drawRect(new Rect(0, 0, 200, 200), paint);
paint.setColor(Color.RED);
canvas.drawRect(new Rect(0, 0, 50, 50), paint);
上面会画出两个正方形,但是,左上角的顶点都是(200, 200),我们如果想第二个小的红正方形的顶点是(0, 0),怎么办?除了上面的反向位移,另外一个方法就是save()和restore()了,比如一开始保存一下画布,相当于单独开辟了一层空间,绘制完后,再还原一下,恢复到上一层,此时重新绘制的都是新开的一层,原先的一层已保存
canvas.save();
Paint paint = new Paint();
canvas.translate(200, 200);
paint.setColor(Color.YELLOW);
canvas.drawRect(new Rect(0, 0, 200, 200), paint);
canvas.restore();
paint.setColor(Color.RED);
canvas.drawRect(new Rect(0, 0, 50, 50), paint);
这样,也达到了需求。
4)的意思是缩放,如果是5,则是变为原先的五倍;如果是0.5,则是变为原先的0.5倍,即缩小一半。这个变化是指画布的缩放,一旦执行这个操作,后续的在同一层的画布上,所有的绘制都按照这个比例扩大。
Paint paint = new Paint();
canvas.scale(0.5f, 0.5f);
paint.setColor(Color.YELLOW);
canvas.drawRect(new Rect(0, 0, 200, 200), paint);
这个画布缩放了0.5倍,则原先黄色的正方形边长了200,此时画出来了边长缩小一半,变为了100。
canvas.scale(sx, sy, px, py) 这个方法的意思是缩放时加了个位移,我们看一下源码
public final void scale(float sx, float sy, float px, float py) {
translate(px, py);
scale(sx, sy);
translate(-px, -py);
}
意思是先位移了px, py,然后进行了缩放,注意看,是缩放后,然后又反向位移。如果缩放的sx 和 sy 都为1,那么没影响。但如果缩放为0.3,位移为300,也就是说,canvas.scale(0.3f, 0.3f, 300, 300); 此时按照代码分析,先是顶点由(0,0)变为(300,300);这时候进行了缩放,倍数为0.3;这时候又要位移了,数值为-300,但前一步我们缩放为原先的0.3倍,也就是说位移值为 -300 * 0.3 = -90,此时顶点由(300,300)变为了(210,210),这一点容易迷惑人,并不是移动后,有原封不动的回到了原点。
5) 旋转,这个好理解,正数是顺时针旋转,负数是逆时针旋转,注意,旋转的是整个画布,而不是图片旋转了,默认的旋转中心点坐标是(0,0)。rotate(angle, px, py) 的原理和 4) 中的多参数的缩放一个道理,看看它的源码
public final void rotate(float degrees, float px, float py) {
translate(px, py);
rotate(degrees);
translate(-px, -py);
}
这个是可以指定旋转中心点的坐标,比如 canvas.rotate(30, 300, 300); 则是以(300, 300)为中心点旋转的,旋转后,会还原旋转点的坐标为(0,0)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。