作者:彩笔学长
原文地址:
Canvas是一种抽象概念,是2D图形系统中的重要部分,canvas一系列函数最终都是Android 2D图形库Skia的一些列封装,对应在SKCanvas.cpp。canvas在系统中的位置如下图所示:
可以将canvas看成一个透明的图层,使用canvas之后会产生一个透明图层,然后在这个新图层上画图,画完之后覆盖在屏幕上显示,叠加。 比较经典的例子就是:
protected void onDraw(Canvas canvas) { super.onDraw(canvas); //构造一个矩形 Rect rect1 = new Rect(0, 0, 400, 220); //在平移画布前用绿色画下边框 canvas.drawRect(rect1, paint_green); //平移画布后,再用红色边框重新画下这个矩形 canvas.translate(100, 100); canvas.drawRect(rect1, paint_red); }我们首先画了一个绿色矩形框,然后将canvas平移了,接着画了一个红色的矩形框,结果如下:
这里我们会发现,平移了canvas之后绿色矩形框没发生变化!拉近镜头我们仔细看看究竟发生了什么,如何印证canvas每次会产生一个透明图层?
调用canvas.drawRect(rect1, paint_green);时,产生一个Canvas透明图层,由于当时还没有对坐标系平移,所以坐标原点是(0,0);再在系统在Canvas上画好之后,覆盖到屏幕上显示出来,过程如下图(图片来自网络,链接在文后):
然后再第二次调用canvas.drawRect(rect1, paint_red);时,又会重新产生一个全新的Canvas画布,此时由于使用tranlate移动了画布 因而在画图时是以新原点来产生视图的,然后合成到屏幕上,超出部分不显示,最后就是我们看到结果了。
Canvas常用方法
下面来清点一下重要的API,绘制颜色就不赘述了。
绘制基本形状
drawRoundRecf画圆角矩形
// 第一种 RectF rectF = new RectF(100,100,400,400); canvas.drawRoundRect(rectF,30,30,paint_red); // 第二种 需要api21,一般常用第一种 // canvas.drawRoundRect(100,100,800,400,30,30,paint_red);
这里是采用第一种方法画出来的,参数30(rx),30(ry)是椭圆的两个半径,用来确定圆角的弧度。
drawOval画椭圆
// 第一种 RectF rectF = new RectF(100,100,500,400); canvas.drawOval(rectF,paint_red); // 第二种 canvas.drawOval(100,100,800,400,paint_red);通常也是使用第一种,画椭圆只需要一个矩形即可,椭圆是改矩形的内切。
drawArc画圆弧
// 第一种 public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint){} // 第二种 public void drawArc(float left, float top, float right, float bottom, float startAngle,float sweepAngle, boolean useCenter, @NonNull Paint paint) {}可以看出这里使用了椭圆的形状,除此之外加上了三个参数:
startAngle // 开始角度 sweepAngle // 扫过角度 useCenter // 是否和中心点连成一个封闭的图形 RectF rectF = new RectF(100, 100, 400, 400); RectF rectF1 = new RectF(200, 200, 500, 500); canvas.drawArc(rectF, 0, 40, true, paint_green); canvas.drawArc(rectF1, 0, 40, false, paint_green);
画圆弧要清楚,0-40画弧,首先水平那根线是起点,按顺时针40度停止。
drawPath
这个结合path一起使用会非常强大!(path用法也是内涵满满,这里就不展开叙述了)
这里看下canvas中的用法:
public void drawPath(@NonNull Path path, @NonNull Paint paint){}传入路径,和对应的画笔即可:
Path path = new Path(); path.moveTo(50,50); path.quadTo(30,220,320,450); canvas.drawPath(path,paint_green);这里使用path画了一条贝塞尔曲线。