moveTo():设置下一次path的起点。
lineTo():通过直线连接上个点与参数指定点。没有上一个点的话,上一个点就是(0,0)。
setLastPoint():重置当前path中的上一个点。
set():将当前path重置为参数path。
offset():对当前的path进行平移。Path类型参数是有来存储平移后的path的,如果没有就直接操作修改当前的Path。
arcTo():指定一个弧形做为path中的一部分。boolean型变量,如果为false则弧线的起点通过直接连接到path的上一个点,如果为true,则不连接到path的上一个点。但弧线的终点始终连接到path的下一个点。如下:
addArc():将一个弧形添加到path中,并且后继的lineTo()等操作都只与弧形的起始点相连,并不与path的moveTo()指定的点相关,相当于新建了一个path,后继的所有操作都在该path中进行。
它与arcTo()的区别在于,arcTo()是原path中的一部分,弧形的起始点也是path中的两个点,而addArc()却是新建了一个path,后继的所有操作只是修改该path而对原path这无影响。
setFillType():设置path填充模式。填充时需要先判断要填充的点是否在path内。判断方法有两种:奇偶规则与非零环绕数规则(链接),两个规则得到的结果并不是完全一样。WINDING:以非零环绕数规则进行填充。EVEN_ODD:以奇偶规则进行填充。INVERSE_***:与***规则相反,***规则判断在内,则INVERSE_***判断在外。
rLineTo():新点相对于path的最后一个点的坐标,而lineTo()指定的是新点相对于原点的坐标。其余几个以r开头的方法都类似。
quadTo()与cubicTo():前者绘制二阶贝塞尔曲线,后才是三阶的贝塞尔曲线。系统中只提供到了三阶贝塞尔曲线(ps中钢笔工具也类似),因为复杂的图形可以拆分成多个三阶曲线进行拼合即可。
op():有一个Path对象时,本path为path1,参数path为path2,使用执行Op参数指定的交,并或差集,并将结果赋值给本path对象。有两个path对象时,第一个为path1,第二个为path2,并将结果赋值给本path对象。
reset():清除Path中的直接、曲线等数据,但保留Path的FillType。类似于创建一个新的path,并且将该对象的filltype设置为旧path的filltype。
rewind():清除Path中存储的直线、曲线等。但是会保留内部的数据结构以便快速复用——当每一次path都含有相同数目的点时,rewind()可以显著地提升性能。参考
类似于Region.Op。
DIFFERENCE:从path1中减去path2。
INTERSECT:取两者的交集。
UNION:取两者并集。
XOR:两者并集并减去两者交集。
REVERSE_DIFFERENCE:与DIFFERENCE相反,从path2减去path1。
动态图
ps中的钢笔工具就是利用贝塞尔曲线完成的,而且复杂的图形也是通过多个三阶贝塞尔曲线连接形成的。如下图,是用ps中钢笔工具填充的蓝色部分,蓝色部分的曲线是由两个三阶贝塞尔曲线连接的。
示例
canvas.drawColor(Color.GRAY);
path.reset();
path.moveTo(0, getHeight() / 2);
path.cubicTo(getWidth() / 3, getHeight() / 2 + 200 - 400 * factor, getWidth() * 2 / 3, getHeight() / 2 - 200 + factor * 400, getWidth(), getHeight() / 2);
path.lineTo(getWidth(), getHeight());
path.lineTo(0, getHeight());
path.close();
canvas.drawPath(path, paint);
不断改变factor的值,就不断修改控制点的值,会造成整个图片区域不断变动,成为一种动态效果。用于测量Path。Path与PathMeasure关联后,并不会影响原来的path,而且原来的path修改后必须通过setPath()方法与PathMeasure()进行再次关联。
PathMeasure(),PathMeasure(Path,boolean forceClosed):构造函数。传入的path是要被测量的,forceClosed表示是否强制close该path。Path与PathMeasure()关联之后,无论boolean型的变量为true还是false,都不会影响之前的path。forceClosed为true时,会强制闭合path,因此得到的path长度可能比path原本的长度要长——因为连接了path的起始点。
setPath():将path与PathMeasure进行关联,参数与构造方法中的含义一样。
isClosed():是否关闭。如果构造函数中的forceClosed为true,则该广场的返回值一定为true。为false的话,就要看原来的path是否闭合了。
getLength():返回path的长度。如果返回0,则代表着当前的measure没有关联path对象。
getSegment():截取path中的一部分。前两个参数表示截取的部分的起点距离path起点的距离,终点距离path起点的距离。截取的部分将会添加到的第三个参数dst中。第四个参数为true的话,则截取的path保持原样;为false的话,则截取的片段的起点被移动到dst的最后一个点上,以保证dst的连续性。
nextContour():跳转下一个曲线或直线上。一个path可以由多条直线或曲线构成,而上面的方法都只是在第一条线段上运行,如果想测量别的线段就需要使用nextContour()跳转到下一个线段了。
getPosTan(distance,pos,tan):获取与path起始相隔distance距离的点的坐标以及该点处切线的正切值——其值为tan[1]/tan[0]。坐标值会存储在pos中,而该位置处的正切值会存储在tan中。
getMatrix():其作用于getPosTan()一样,只不过将pos与tan的值封装到了matrix中,省却了拿到pos与tan值后进行旋转与位移的操作。
用path勾勒出一个具体的形状,并使用PathMeasure#getSegment()截取这个path的一部分,然后动态修改截取的长度。并将截取的部分绘制到canvas上,就达到了动态生成的效果。
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.GRAY);
canvas.translate(getWidth() / 2, getHeight() / 2);
if (path == null) {
path = new Path();
path.moveTo(-130 + 50 * (float) Math.sin(Math.PI / 4), -130 + 50 * (float) Math.sin(Math.PI / 4));
path.addArc(new RectF(-180, -180, -80, -80), 45, 359.9f);
path.lineTo(-50, -50);
measure.setPath(path, false);
length = measure.getLength();
measure.nextContour();
length += measure.getLength();
measure.setPath(path, false);
p = new Path();
}
p.reset();
measure.getSegment(0, length * (1 - factor), p, true);
canvas.drawPath(p, paint);
}
不断修改factor的值,则可以达到动态显示动画。