内容来自:
安卓自定义View进阶-Path之基本操作Path 从懵逼到精通——基本操作Path类封装了直线段,二次贝塞尔曲线和三次贝塞尔曲线的几何路径。
作用相关方法备注移动起点moveTo移动下一次操作的起点位置设置终点setLastPoint重置当前path中最后一个点位置,如果在绘制之前调用,效果和moveTo相同连接直线lineTo添加上一个点到当前点之间的直线到Path闭合路径close连接第一个点连接到最后一个点,形成一个闭合区域添加内容addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path (注意addArc和arcTo的区别)是否为空isEmpty判断Path是否为空是否为矩形isRect判断path是否是一个矩形替换路径set用新的路径替换到当前路径所有内容偏移路径offset对当前路径之前的操作进行偏移(不会影响之后的操作)贝塞尔曲线quadTo, cubicTo分别为二次和三次贝塞尔曲线的方法rXxx方法rMoveTo, rLineTo, rQuadTo, rCubicTo不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)填充模式setFillType, getFillType, isInverseFillType, toggleInverseFillType设置,获取,判断和切换填充模式提示方法incReserve提示Path还有多少个点等待加入(这个方法貌似会让Path优化存储结构)布尔操作(API19)op对两个Path进行布尔运算(即取交集、并集等操作)计算边界computeBounds计算Path的边界重置路径reset, rewind清除Path中的内容 reset 不保留内部数据结构,但会保留FillType. rewind会保留内部的数据结构,但不保留FillType矩阵操作transform矩阵变换lineTo绘制直线,起点是上次调用的最后一个点的坐标,如果没有,则为坐标原点
canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心(宽高数据在onSizeChanged中获取) Path path = new Path(); // 创建Path path.lineTo(200, 200); // lineTo path.lineTo(200,0); canvas.drawPath(path, mPaint); // 绘制PathPath.Direction表示是顺时针还是逆时针
类型解释翻译CWclockwise顺时针CCWcounter-clockwise逆时针如下的例子:
canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 canvas.scale(1,-1); // <-- 注意 翻转y坐标轴 Path path = new Path(); Path src = new Path(); path.addRect(-200,-200,200,200, Path.Direction.CW); src.addCircle(0,0,100, Path.Direction.CW); path.addPath(src,0,200); mPaint.setColor(Color.BLACK); // 绘制合并后的路径 canvas.drawPath(path,mPaint);内容来自:安卓自定义View进阶-Path之贝塞尔曲线
内容来自:安卓自定义View进阶-Path之完结篇
rXxx方法的坐标使用的是相对位置(基于当前点的位移),而之前方法的坐标是绝对位置(基于当前坐标系的坐标)。
Inverse 和含义是“相反,对立”,说明反奇偶规则刚好与奇偶规则相反,例如对于一个矩形而言,使用奇偶规则会填充矩形内部,而使用反奇偶规则会填充矩形外部
Android与填充模式相关的方法
方法作用setFillType设置填充规则getFillType获取当前填充规则isInverseFillType判断是否是反向(INVERSE)规则toggleInverseFillType切换填充规则(即原有规则与反向规则之间相互切换)如下的例子,内外2个矩形,先使用EVEN_ODD填充规则
mPaint.setStyle(Paint.Style.FILL); // 设置画布模式为填充 mPaint.setColor(Color.RED); canvas.translate(mWidth / 2, mHeight / 2); // 移动画布(坐标系) Path outerPath = new Path(); // 创建Path outerPath.addRect(-400, -400, 400, 400, Path.Direction.CW); // 给Path中添加一个矩形 outerPath.setFillType(Path.FillType.EVEN_ODD); // 设置Path填充模式为 奇偶规则 //outerPath.setFillType(Path.FillType.INVERSE_EVEN_ODD); // 反奇偶规则 Path innerPath = new Path(); innerPath.addRect(-200,-200,200,200, Path.Direction.CW); // 给Path中添加一个矩形 //合并path outerPath.addPath(innerPath); canvas.drawPath(outerPath, mPaint);效果为:
填充规则为反奇偶填充规则INVERSE_EVEN_ODD,效果为:
当内外矩形都为顺时针,使用非零环绕规则WINDING
当内外矩形都为顺时针,使用反非零环绕规则INVERSE_WINDING
当内矩形为逆时针,外矩形为顺时针,使用非零环绕规则WINDING
当内矩形为逆时针,外矩形为顺时针,使用反非零环绕规则INVERSE_WINDING
如下的例子:
mPaint.setStyle(Paint.Style.FILL); canvas.translate(mWidth / 2, mHeight / 2); Path path1 = new Path(); Path path2 = new Path(); Path path3 = new Path(); Path path4 = new Path(); path1.addCircle(0, 0, 200, Path.Direction.CW); path2.addRect(0, -200, 200, 200, Path.Direction.CW); path3.addCircle(0, -100, 100, Path.Direction.CW); path4.addCircle(0, 100, 100, Path.Direction.CCW); if (Build.VERSION.SDK_INT >= 19) { path1.op(path2, Path.Op.DIFFERENCE); path1.op(path3, Path.Op.UNION); path1.op(path4, Path.Op.DIFFERENCE); } canvas.drawPath(path1, mPaint);这个方法主要作用是计算Path所占用的空间以及所在位置,方法如下:
void computeBounds (RectF bounds, boolean exact)