Canvas简介
Canvas也就是Android中的画布,它保存了一些列的draw方法,你可以是用Canvas绘制图形、文字和位图等,其功能可谓是十分的强大,几乎可以绘制所有的图像和文字。既然Canvas功能如此强大,其丰富了Android的图形,也是Android图形学不可或缺的类,而学习和熟练Canvas,可谓是学习Android UI的重点之一,接下来我们开始学习Canvas的API。
Canvas绘图
既然Canvas提供了绘制图形的功能,那么看下其对应的API有那些。
绘制直线
public class CanvasView extends View {
Paint paint;
public CanvasView(Context context) {
this(context,null);
}
public CanvasView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
canvas.drawLine(0, 0, 100, 100, paint);
}
}
使用数组,绘制直线
float []pts = {0,0,100,100,200,200,300,300};
canvas.drawLines(pts, paint);
先绘制(0,0)到(100,100)的直线,然后绘制(200,200)到(300,300)的直线。
定义数组,也可以使用下面语句来绘制直线
drawLines(@Size(multiple = 4) @NonNull float[] pts, int offset, int count, @NonNull Paint paint)
pts:坐标数组 offset:设置线的间隔距离 count:绘制直线的条数 paint:画笔
drawPoint
绘制点:
drawPoint(float x, float y, @NonNull Paint paint)
绘制多个点:
float []pts = {0,0,100,100,200,200,300,300};
canvas.drawPoints(pts, paint);
drawRect
绘制矩形,矩形区域有两种表示方式:Rect和RectF,Rect表示int类型,RectF表示float类型。
RectF r = new RectF(100, 100, 400, 500);
canvas.drawRect(r, paint);
也可以如下表示:
drawRect(float left, float top, float right, float bottom, @NonNull Paint paint)
drawRoundRect
使用drawRoundRect,绘制圆角矩形
drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint)
rx:x轴的圆角半径大小 ry:y轴的圆角半径大小
RectF r = new RectF(100, 100, 400, 500);
canvas.drawRoundRect(r, 100, 100, paint);
drawCircle
绘制圆 :
drawCircle(float cx, float cy, float radius, @NonNull Paint paint)
cx、cy:圆心坐标 radius:半径
canvas.drawCircle(300, 300, 200, paint);
drawOval
使用drawOval函数绘制椭圆
drawOval(@NonNull RectF oval, @NonNull Paint paint) oval:定义的矩形 paint:画笔
除了上述方法参数,可以使用以下方法参数:
drawOval(float left, float top, float right, float bottom, @NonNull Paint paint)
之所以提供一个矩形区域,是因为该椭圆是矩形的内切圆。
RectF r = new RectF(100, 100, 400, 500);
canvas.drawRect(r, paint);
canvas.drawOval(r, paint);
drawArc
使用drawArc方法绘制扇形图。
drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter,@NonNull Paint paint)
oval:矩形,该扇形是在矩形区域内绘制的,而且围绕着矩形的中心点来绘制。 startAngle:开始角度,相对X轴正方向 sweepAngle:画多少角度的弧度 useCenter:false表示只有一个纯弧线,true表示闭合的边 paint:画笔
RectF r = new RectF(100, 100, 400, 500);
canvas.drawRect(r, paint);
canvas.drawArc(r, 0, 90, true, paint);//顺时针旋转90度
drawPath
使用drawPath来绘制路径,更加灵活的绘制出各式各样的图形。绘制路径,我们需要理解以下几个方法: 1)moveTo(float x, float y):画笔落笔的位置 2)lineTo(float x, float y):画笔移动的到(x,y)坐标,并沿着绘制出路径。 3)cubicTo(float x1, float y1, float x2, float y2,float x3, float y3):实现贝塞尔曲线路径, (x1,y1) 为控制点,(x2,y2)为控制点,(x3,y3) 为结束点。 4)quadTo(float x1, float y1, float x2, float y2):也是绘制贝塞尔曲线,即椭圆曲线。(x1,y1)控制点,(x2,y2)结束点。 5)arcTo:绘制弧线。
Path path = new Path();
path.moveTo(100, 100);
path.lineTo(200, 100);
path.cubicTo(250, 200, 350, 300, 450, 400);
path.close();
canvas.drawPath(path, paint);
弧线
RectF r = new RectF(100, 100, 400, 500);
Path path = new Path();
path.addArc(r, 30, 70);
canvas.drawPath(path, paint);
圆角矩形路径
RectF r = new RectF(100, 100, 400, 500);
Path path = new Path();
float radii[] = {//左上角开始,顺时针依次的角度
10,//x1
10,//y1
10,//x2
10,//y2
10,//x3
10,//y30
50,//x4
60};//y4
path.addRoundRect(r, radii, Path.Direction.CCW);
canvas.drawPath(path, paint);
Canvas变换技巧
Canvas变换包括: 1)平移(Translate) 2)缩放(Scale) 3)旋转(Rotate) 4)斜拉画布(Skew) 5)裁剪画布(clip)
平移
RectF r = new RectF(0, 0, 400, 500);
canvas.drawRect(r, paint);
paint.setColor(Color.BLUE);
//将画布平移
canvas.translate(50, 50);
canvas.drawRect(r, paint);
上图中画布平移了,蓝色的矩形平移了,但是红色的矩形没有平移,是因为当canvas执行drawXXX的时候就会新建一个新的画布图层,而平移知识平移新的图层。
RectF r = new RectF(0, 0, 400, 500);
canvas.drawRect(r, paint);
paint.setColor(Color.BLUE);
//将画布平移
canvas.translate(50, 50);
canvas.drawRect(r, paint);
RectF r2 = new RectF(0, 0, 400, 500);
paint.setColor(Color.GREEN);
canvas.drawRect(r2, paint);
从上图中可以看到绿色矩形覆盖了蓝色的矩形,虽然draw的时候,新建了一个画布图层,但是还是会沿用之前设置的平移变换。不可逆的。解决这种情况需要使用save和restore来解决。
缩放
scale(float sx, float sy)
sx、sy:分别对x/y方向的一个缩放系数,画布的缩放会导致里面所有的绘制的东西都会有一个缩放效果。
RectF r = new RectF(0, 0, 400, 500);
canvas.drawRect(r, paint);
paint.setColor(Color.BLUE);
canvas.scale(1.5f, 0.5f);
canvas.drawRect(r, paint);
旋转
rotate(float degrees),degrees:旋转角度,顺时针旋转 rotate(float degrees, float px, float py),degrees旋转角度,(px,py)旋转中心点坐标
RectF r = new RectF(200, 200, 400, 500);
canvas.drawRect(r, paint);
paint.setColor(Color.BLUE);
canvas.rotate(45);
canvas.drawRect(r, paint);
斜拉画布
skew(float sx, float sy):sx,sy倾斜度
RectF r = new RectF(200, 200, 400, 500);
canvas.drawRect(r, paint);
paint.setColor(Color.BLUE);
canvas.skew(1.73f, 0);
canvas.drawRect(r, paint);
裁剪画布
clipRect(@NonNull Rect rect) rect:裁剪的矩形区域
RectF r = new RectF(200, 200, 400, 500);
canvas.drawRect(r, paint);
paint.setColor(Color.BLUE);
canvas.clipRect(new Rect(250, 250, 300, 400));
canvas.drawColor(Color.YELLOW);
理解canvas
Canvas画布的正确的理解: 1)当canvas执行drawXXX的时候就会新建一个新的画布图层
2)虽然后面新建了一个画布图层,但是还是会沿用之前设置的平移变换。不可逆的。(save和restore来解决)