一.简介
Canvas 美[ˈkænvəs] 画布
Canvas绘图有三个基本要素:Canvas、绘图坐标系以及Paint。
- Canvas是画布,我们通过Canvas的各种drawXXX方法将图形绘制到Canvas上面,在drawXXX方法中我们需要传入要绘制的图形的坐标形状,还要传入一个画笔Paint。
- drawXXX方法以及传入其中的坐标决定了要绘制的图形的形状,比如drawCircle方法,用来绘制圆形,需要我们传入圆心的x和y坐标,以及圆的半径。
- drawXXX方法中传入的画笔Paint决定了绘制的图形的一些外观,比如是绘制的图形的颜色,再比如是绘制圆面还是圆的轮廓线等。
- Canvas的drawXXX方法中传入的各种坐标指的都是绘图坐标系中的坐标。在初始状况下,绘图坐标系的坐标原点在View的左上角。
但绘图坐标系可以改变,例如translate方法,可以平移坐标系。且坐标系的位移是基于当前位置移动,而不是每次基于屏幕左上角的(0,0)点移动。
二.Canvas的常用操作速查表
操作类型 | 相关API | 备注 |
---|---|---|
绘制颜色 | drawColor, drawRGB, drawARGB | 使用单一颜色填充整个画布 |
绘制基本形状 | drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc | 依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧 |
绘制图片 | drawBitmap, drawPicture | 绘制位图和图片 |
绘制文本 | drawText, drawPosText, drawTextOnPath | 依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字 |
绘制路径 | drawPath | 绘制路径,绘制贝塞尔曲线时也需要用到该函数 |
顶点操作 | drawVertices, drawBitmapMesh | 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用 |
画布剪裁 | clipPath, clipRect | 设置画布的显示区域 |
画布快照 | save, restore, saveLayerXxx, restoreToCount, getSaveCount | 依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 回滚到指定状态、 获取保存次数 |
画布变换 | translate, scale, rotate, skew | 依次为 位移、缩放、 旋转、错切 |
Matrix(矩阵) | getMatrix, setMatrix, concat | 实际画布的位移,缩放等操作的都是图像矩阵Matrix,只不过Matrix比较难以理解和使用,故封装了一些常用的方法。 |
三.实战
绘制颜色 drawARGB:
绘制颜色是填充整个画布,常用于绘制底色。
- 新建CanvasView类继承View
- 重写onDraw
public class CanvasView extends View { //在代码中定义和使用时用到的 public CanvasView(Context context) { super(context); } //在xml中定义我们的自定义属性时用到 public CanvasView(Context context, AttributeSet attrs) { super(context, attrs); } //在View中画出我们需要的内容 @Override protected void onDraw(Canvas canvas) { canvas.drawARGB(255, 139, 197, 186); } }
绘制画布
绘制点 drawPoint:
- 在构造函数中初始化画笔
- 重写onDraw
public class CanvasView extends View { private Paint mPaint; //在代码中定义和使用时用到的 public CanvasView(Context context) { super(context); init(); } //在xml中定义我们的自定义属性时用到 public CanvasView(Context context, AttributeSet attrs) { super(context, attrs); init(); } //在构造函数中初始化画笔 private void init() { mPaint = new Paint(); mPaint.setColor(Color.BLACK); //设置画笔颜色 mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充 mPaint.setStrokeWidth(10f); //设置画笔宽度为10px } //在View中画出我们需要的内容 @Override protected void onDraw(Canvas canvas) { canvas.drawPoint(100, 100, mPaint); //在坐标(100,100)位置绘制一个点 canvas.drawPoints(new float[]{ //绘制一组点,坐标位置由float数组指定 200, 200, 300, 400, 400, 500 }, mPaint); } }
绘制点
绘制直线 drawLine:
protected void onDraw(Canvas canvas) { mPaint.setColor(Color.GREEN);// 设置绿色 canvas.drawLine(60, 40, 100, 40, mPaint);// 画线 canvas.drawLine(110, 40, 190, 80, mPaint);// 斜线 canvas.drawLines(new float[]{ // 绘制一组线 每四数字(两个点的坐标)确定一条线 100,200,200,200, 100,300,200,300 },mPaint); }
绘制直线
绘制矩形 drawRect:
确定确定一个矩形最少需要四个数据,就是对角线的两个点的坐标值,这里一般采用左上角和右下角的两个点的坐标。
protected void onDraw(Canvas canvas) { //取得画布的宽高 int canvasWidth = canvas.getWidth(); int canvasHeight = canvas.getHeight(); //设置画笔的填充色是蓝色 mPaint.setColor(Color.BLUE); int left1 = 10; int top1 = 10; int right1 = canvasWidth / 3; int bottom1 = canvasHeight /3; canvas.drawRect(left1, top1, right1, bottom1, mPaint); //修改画笔颜色 mPaint.setColor(Color.RED); int left2 = canvasWidth / 3 * 2; int top2 = 10; int right2 = canvasWidth - 10; int bottom2 = canvasHeight / 3; canvas.drawRect(left2, top2, right2, bottom2, mPaint); }
- 简单画了下法国国旗
绘制矩形
绘制圆角矩形 drawRoundRect:
protected void onDraw(Canvas canvas) { mPaint.setColor(0xff8bc5ba);//A:ff,R:8b,G:c5,B:ba RectF rectF = new RectF(10,10,300,150); //这里的圆弧是椭圆的圆弧,所以要设置椭圆的两个半径 canvas.drawRoundRect(rectF,10,10,mPaint); }
rx,ry
绘制圆角矩形
绘制圆、圆环和椭圆 drawCircle、drawOval:
protected void onDraw(Canvas canvas) { mPaint.setColor(0xff8bc5ba); mPaint.setAntiAlias(true); //设置画笔为抗锯齿模式,不然画出来太丑了 mPaint.setStyle(Paint.Style.FILL);//默认绘图为填充模式 int canvasWidth = canvas.getWidth(); int canvasHeight = canvas.getHeight(); int halfCanvasWidth = canvasWidth / 2; int R = canvasHeight / 9; // 绘制一个矩形的内切椭圆 RectF rectF = new RectF(100, 10, 370, 150); canvas.drawOval(rectF, mPaint); // 绘制一个圆心坐标在(halfCanvasWidth,250),半径为R 的圆 canvas.drawCircle(halfCanvasWidth, 250, R, mPaint); //通过绘制两个圆形成圆环 //1. 首先绘制大圆 canvas.drawCircle(halfCanvasWidth, 450, R, mPaint); //2. 然后绘制小圆,让小圆覆盖大圆,形成圆环效果 int r = (int) (R * 0.75); mPaint.setColor(0xffffffff);//将画笔设置为白色,画小圆 canvas.drawCircle(halfCanvasWidth, 450, r, mPaint); //通过画笔的描边绘图模式绘制圆环 mPaint.setColor(0xff8bc5ba);//设置颜色 mPaint.setStyle(Paint.Style.STROKE);//绘图为描边模式 float strokeWidth = (float) (R * 0.25); //设置线条宽度 mPaint.setStrokeWidth(strokeWidth); canvas.drawCircle(halfCanvasWidth, 650, R, mPaint); }
绘制圆、圆环、椭圆
- 简要介绍Paint的模式
- STROKE 描边,把边给填充颜色
- FILL 填充,填充边中的内容
- FILL_AND_STROKE 描边加填充,就是把上面两个合起来
绘制圆弧 drawArc:
Canvas中提供了drawArc方法用于绘制弧,这里的弧指两种:弧面和弧线,弧面即用弧围成的填充面,弧线即为弧面的轮廓线。
public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint){}
- oval是RecF类型的对象,其定义了椭圆的形状。
- startAngle指的是绘制的起始角度,如果传入的startAngle小于0或者大于等于360,那么用startAngle对360进行取模后作为起始绘制角度。
- sweepAngle指的是从startAngle开始沿着钟表的顺时针方向旋转扫过的角度。如果sweepAngle大于等于360,那么会绘制完整的椭圆弧。如果sweepAngle小于0,那么会用sweepAngle对360进行取模后作为扫过的角度。
-
useCenter是个boolean值,如果为true,表示在绘制完弧之后,用椭圆的中心点连接弧上的起点和终点以闭合弧;如果值为false,表示在绘制完弧之后,弧的起点和终点直接连接,不经过椭圆的中心点。
protected void onDraw(Canvas canvas) { int canvasWidth = canvas.getWidth(); int canvasHeight = canvas.getHeight(); //把画布分成五份 float ovalHeight = canvasHeight / 5; float left = 10 ; float top = 0; float right = canvasWidth - left; float bottom= ovalHeight; RectF rectF = new RectF(left, top, right, bottom); mPaint.setAntiAlias(true); //抗锯齿 mPaint.setStrokeWidth(5);//设置线宽 mPaint.setColor(0xff8bc5ba);//设置颜色 mPaint.setStyle(Paint.Style.FILL);//默认设置画笔为填充模式 //绘制用drawArc绘制完整的椭圆 canvas.drawArc(rectF, 0, 360, true, mPaint); //绘制椭圆的四分之一,起点是0度,到90度 canvas.translate(0, ovalHeight ); //绘图坐标系平移操作,x轴移动0,y轴移动五分之一个画布长度 canvas.drawArc(rectF, 0, 90, true, mPaint); //绘制椭圆的四分之一,将useCenter设置为false canvas.translate(0, ovalHeight ); canvas.drawArc(rectF, 0, 90, false, mPaint); //绘制椭圆的四分之一,只绘制轮廓线 mPaint.setStyle(Paint.Style.STROKE);//设置画笔为描边模式 canvas.translate(0, ovalHeight ); canvas.drawArc(rectF, 0, 90, true, mPaint); //绘制带有轮廓线的椭圆的四分之一 //1. 先绘制椭圆的填充部分 mPaint.setStyle(Paint.Style.FILL);//设置画笔为填充模式 canvas.translate(0, ovalHeight ); canvas.drawArc(rectF, 0, 90, true, mPaint); //2. 再绘制椭圆的轮廓线部分 mPaint.setStyle(Paint.Style.STROKE);//设置画笔为线条模式 mPaint.setColor(0xff0000ff);//设置轮廓线条为蓝色 canvas.drawArc(rectF, 0, 90, true, mPaint); }
绘制圆弧
自定义饼图:
学了那么大堆基础终于可以画个能用的图了
自定义饼图
protected void onDraw(Canvas canvas) { RectF rectF = new RectF(100, 100, 400, 400); mPaint.setAntiAlias(true); //抗锯齿 mPaint.setStrokeWidth(5);//设置线宽 mPaint.setColor(0xFFCCFF00);//设置颜色 mPaint.setStyle(Paint.Style.FILL);//默认设置画笔为填充模式 canvas.drawArc(rectF, 0, 110, true, mPaint); mPaint.setColor(0xff8bc5ba);//设置颜色 canvas.drawArc(rectF, 110, 50, true, mPaint); mPaint.setColor( 0xFF800000);//设置颜色 canvas.drawArc(rectF, 160, 80, true, mPaint); mPaint.setColor(0xFFFF8C69);//设置颜色 canvas.drawArc(rectF, 240, 120, true, mPaint); }
这里是 项目地址
参考
http://blog.csdn.net/iispring/article/details/49770651
https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B02%5DCanvas_BasicGraphics.md
来自:http://www.jianshu.com/p/282958cdbf25