你的位置:Android开发中文站 > Android开发 > 新手入门 > Android中Canvas绘图基础详解(附源码下载)
Android中Canvas绘图基础详解(附源码下载)新手入门 AndroidChina 1年前 (2015-11-24) 3560浏览
Android中,如果我们想绘制复杂的自定义View或游戏,我们就需要熟悉绘图API。Android通过Canvas类暴露了很多drawXXX方法,我们可以通过这些方法绘制各种各样的图形。Canvas绘图有三个基本要素:Canvas、绘图坐标系以及Paint。Canvas是画布,我们通过Canvas的各种drawXXX方法将图形绘制到Canvas上面,在drawXXX方法中我们需要传入要绘制的图形的坐标形状,还要传入一个画笔Paint。drawXXX方法以及传入其中的坐标决定了要绘制的图形的形状,比如drawCircle方法,用来绘制圆形,需要我们传入圆心的x和y坐标,以及圆的半径。drawXXX方法中传入的画笔Paint决定了绘制的图形的一些外观,比如是绘制的图形的颜色,再比如是绘制圆面还是圆的轮廓线等。Android系统的设计吸收了很多已有系统的诸多优秀之处,比如Canvas绘图。Canvas不是Android所特有的,Flex和Silverlight都支持Canvas绘图,Canvas也是HTML5标准中的一部分,主流的现代浏览器都支持用JavaScript在Canvas上绘图,如果你用过HTML5中的Canvas,你会发现Android的Canvas的绘图API与其很相似。总之,Canvas绘图不是Android所特有的。
为了演示Android中各种drawXXX方法的时候,我做了一个App,通过单击相应的按钮绘制相应的图形,主界面如下所示:
Canvas坐标系与绘图坐标系Canvas绘图中牵扯到两种坐标系:Canvas坐标系与绘图坐标系。
Canvas坐标系指的是Canvas本身的坐标系,Canvas坐标系有且只有一个,且是唯一不变的,其坐标原点在View的左上角,从坐标原点向右为x轴的正半轴,从坐标原点向下为y轴的正半轴。
Canvas的drawXXX方法中传入的各种坐标指的都是绘图坐标系中的坐标,而非Canvas坐标系中的坐标。默认情况下,绘图坐标系与Canvas坐标系完全重合,即初始状况下,绘图坐标系的坐标原点也在View的左上角,从原点向右为x轴正半轴,从原点向下为y轴正半轴。但不同于Canvas坐标系,绘图坐标系并不是一成不变的,可以通过调用Canvas的translate方法平移坐标系,可以通过Canvas的rotate方法旋转坐标系,还可以通过Canvas的scale方法缩放坐标系,而且需要注意的是,translate、rotate、scale的操作都是基于当前绘图坐标系的,而不是基于Canvas坐标系,一旦通过以上方法对坐标系进行了操作之后,当前绘图坐标系就变化了,以后绘图都是基于更新的绘图坐标系了。也就是说,真正对我们绘图有用的是绘图坐标系而非Canvas坐标系。
为了更好的理解绘图坐标系,请看如下的代码:
//绘制坐标系 private void drawAxis(Canvas canvas){ int canvasWidth = canvas.getWidth(); int canvasHeight = canvas.getHeight(); paint.setStyle(Paint.Style.STROKE); paint.setStrokeCap(Paint.Cap.ROUND); paint.setStrokeWidth(6 * density); //用绿色画x轴,用蓝色画y轴 //第一次绘制坐标轴 paint.setColor(0xff00ff00);//绿色 canvas.drawLine(0, 0, canvasWidth, 0, paint);//绘制x轴 paint.setColor(0xff0000ff);//蓝色 canvas.drawLine(0, 0, 0, canvasHeight, paint);//绘制y轴 //对坐标系平移后,第二次绘制坐标轴 canvas.translate(canvasWidth / 4, canvasWidth /4);//把坐标系向右下角平移 paint.setColor(0xff00ff00);//绿色 canvas.drawLine(0, 0, canvasWidth, 0, paint);//绘制x轴 paint.setColor(0xff0000ff);//蓝色 canvas.drawLine(0, 0, 0, canvasHeight, paint);//绘制y轴 //再次平移坐标系并在此基础上旋转坐标系,第三次绘制坐标轴 canvas.translate(canvasWidth / 4, canvasWidth / 4);//在上次平移的基础上再把坐标系向右下角平移 canvas.rotate(30);//基于当前绘图坐标系的原点旋转坐标系 paint.setColor(0xff00ff00);//绿色 canvas.drawLine(0, 0, canvasWidth, 0, paint);//绘制x轴 paint.setColor(0xff0000ff);//蓝色 canvas.drawLine(0, 0, 0, canvasHeight, paint);//绘制y轴 }界面如下所示:
第一次绘制绘图坐标系时,绘图坐标系默认情况下和Canvas坐标系重合,所以绘制出的坐标系紧贴View的上侧和左侧;
第二次首先将坐标轴向右下角平移了一段距离,然后绘制出的坐标系也就整体向右下角平移了;
第三次再次向右下角平移,并旋转了30度,图上倾斜的坐标系即最后的绘图坐标系。
Canvas中的drawARGB可以用来对整个Canvas以某种统一的颜色整体绘制,四个参数分别是Alpha、Red、Green、Blue,取值都是0-255。
使用代码如下:
界面如下所示:
Canvas中用drawText方法绘制文字,代码如下所示:
private void drawText(Canvas canvas){ int canvasWidth = canvas.getWidth(); int halfCanvasWidth = canvasWidth / 2; float translateY = textHeight; //绘制正常文本 canvas.save(); canvas.translate(0, translateY); canvas.drawText("正常绘制文本", 0, 0, paint); canvas.restore(); translateY += textHeight * 2; //绘制绿色文本 paint.setColor(0xff00ff00);//设置字体为绿色 canvas.save(); canvas.translate(0, translateY);//将画笔向下移动 canvas.drawText("绘制绿色文本", 0, 0, paint); canvas.restore(); paint.setColor(0xff000000);//重新设置为黑色 translateY += textHeight * 2; //设置左对齐 paint.setTextAlign(Paint.Align.LEFT);//设置左对齐 canvas.save(); canvas.translate(halfCanvasWidth, translateY); canvas.drawText("左对齐文本", 0, 0, paint); canvas.restore(); translateY += textHeight * 2; //设置居中对齐 paint.setTextAlign(Paint.Align.CENTER);//设置居中对齐 canvas.save(); canvas.translate(halfCanvasWidth, translateY); canvas.drawText("居中对齐文本", 0, 0, paint); canvas.restore(); translateY += textHeight * 2; //设置右对齐 paint.setTextAlign(Paint.Align.RIGHT);//设置右对齐 canvas.save(); canvas.translate(halfCanvasWidth, translateY); canvas.drawText("右对齐文本", 0, 0, paint); canvas.restore(); paint.setTextAlign(Paint.Align.LEFT);//重新设置为左对齐 translateY += textHeight * 2; //设置下划线 paint.setUnderlineText(true);//设置具有下划线 canvas.save(); canvas.translate(0, translateY); canvas.drawText("下划线文本", 0, 0, paint); canvas.restore(); paint.setUnderlineText(false);//重新设置为没有下划线 translateY += textHeight * 2; //绘制加粗文字 paint.setFakeBoldText(true);//将画笔设置为粗体 canvas.save(); canvas.translate(0, translateY); canvas.drawText("粗体文本", 0, 0, paint); canvas.restore(); paint.setFakeBoldText(false);//重新将画笔设置为非粗体状态 translateY += textHeight * 2; //文本绕绘制起点顺时针旋转 canvas.save(); canvas.translate(0, translateY); canvas.rotate(20); canvas.drawText("文本绕绘制起点旋转20度", 0, 0, paint); canvas.restore(); }界面如下所示:
对以上代码进行一下说明:
drawPoint