这篇博文主要说一下自定义 View 中的路径。
在上一篇博文当中,可以画一些简单的图形了,但是学会了路径,就可以画一些较为复杂的图像了。
Android 提供了 drawPath(Path path, Paint paint)
这个方法来通过路径绘制图像。其参数 Path 就是今天的主要内容。
Path 封装了由直线、二次曲线和三次曲线组成的复合(多轮廓)几何路径。我们可以调用 canvas.drawPath 方法来绘制图形,也可以将文本绘制在路径上,也可以按照路径裁剪图形。
基本上 Path 可以分为几大类:
addXXX
- addCircle(float x, float y, float radius, Path.Direction dir):向路径中添加一个圆。参数说明:
- float x:圆心 X 坐标
- float y:圆心 Y 坐标
- float radius:圆半径
- Path.Direction dir:绘制圆的方向,分顺时针还是逆时针,当组合图形时候才会有用,这里暂时放下。
- addOval(RectF oval, Path.Direction dir):向路径中添加一个椭圆。
- addOval(float left, float top, float right, float bottom, Path.Direction dir):向路径中添加一个椭圆。
- addRect(RectF rect, Path.Direction dir):向路径中添加一个矩形。
- addRect(float left, float top, float right, float bottom, Path.Direction dir):向路径中添加一个矩形。
- addRoundRect(RectF rect, float rx, float ry, Path.Direction dir):向路径中添加一个圆角矩形。
- addRoundRect(float left, float top, float right, float bottom, float rx, float ry, Path.Direction dir):向路径中添加一个圆角矩形。
- addRoundRect(RectF rect, float[] radii, Path.Direction dir):向路径中添加一个圆角矩形。
- addRoundRect(float left, float top, float right, float bottom, float[] radii, Path.Direction dir):向路径中添加一个圆角矩形。
- addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle):向路径中添加一个弧形。
- addArc(RectF oval, float startAngle, float sweepAngle):向路径中添加一个弧形。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.GRAY);
Path path = new Path();
path.addCircle(300, 300, 200, Path.Direction.CW);
path.addOval(50, 600, 550, 800, Path.Direction.CW);
path.addRect(100, 900, 500, 1300, Path.Direction.CW);
path.addRoundRect(new RectF(100, 1400, 500, 1800), 50, 20, Path.Direction.CW);
path.addArc(100, 1900, 500, 2300, 180, 100);
canvas.drawPath(path, paint);
}
显示如下:
XXXTo
添加一条线到指定点:
- lineTo(float x, float y):从路径终点添加一条直线到 (x,y),如果路径为空,则默认 (0,0)。
- rLineTo(float dx, float dy):从路径上最后一个点添加一条直线到 (x,y),如果该点不存在,则为 (0,0)
将一条圆弧添加到路径:
- arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
- arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)
- arcTo(RectF oval, float startAngle, float sweepAngle)
如果路径为空,则以圆弧起点为起点(相当于多了一个 lineTo)
boolean forceMoveTo:该参数作用是路径的原终点和该圆弧起点是否相连,为 true 时候,圆弧起点和原终点不连接;为 false 时,圆弧起点和原终点相连接。
将一条二次贝塞尔曲线添加到路径:
- quadTo(float x1, float y1, float x2, float y2)
- rQuadTo(float dx1, float dy1, float dx2, float dy2)
将一条三次贝塞尔曲线添加到路径:
- cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
- rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
关于贝塞尔曲线,可以看这里:贝塞尔曲线扫盲
设置轮廓的起始点:
- moveTo(float x, float y)
- rMoveTo(float dx, float dy)
关闭当前路径:
之前说过,路径可以理解为是你画笔在画布上画过的痕迹,在这个你可以顺着这个痕迹去添加文本啦之类的。
既然是痕迹,自然也就有起点和终点,也就是你画布落下和抬起的那两个点。
既然知道了起点和终点,那么 XXXTo 和 rXXXTo 就很好理解了。
一般的 XXXTo 都是以默认起点为起点,这个默认起点通过 moveTo(float x, float y)
方法来设置,如果没有设置起点,则默认 (0, 0)
;
而 rXXXTo 则以已有路径的终点作为起点,如果当前路径为空,自然也就没有终点了,也就以 (0, 0)
为起点;
arcTo 和其他不同,它的默认起点就是该圆弧的起点,也就是说会默认有一个 moveTo(x, y)
到该圆弧中设置的起点。
close() 的作用是将路径闭合,从当前路径的终点连接一条直线到该路径起点。