Android自定义控件(二 .2)Path的基本操作

前面http://www.jianshu.com/p/35765aa6f7d9 所讲的绘制的图形都是基本的简单图形,如矩形,员,圆弧等。如果对于一些复杂的图形(五角星,心形)的绘制,前面的绘图方法就无能为力了。而使用Path不仅可以绘制简单的图形,还能复制一些复杂的图形。
Google官网上Path的链接为:https://developer.android.google.cn/reference/android/graphics/Path.html
google官网上对path的解释为:
- The Path class encapsulates compound (multiple contour) geometric paths consisting of straight line segments, quadratic curves, and cubic curves. It can be drawn with canvas.drawPath(path, paint), either filled or stroked (based on the paint’s Style), or it can be used for clipping or to draw text on a path.
- 大意是Path类封装了直线段,二次bezier曲线,三次bezier曲线等几何路径,可以通过canvas.drawPath(path, paint)方法画出,画笔的类型可以是filled 或者 stroked,可以用于通过路径裁剪或者绘制文本。

Path的相关方法
作用相关方法备注
移动起点moveTo(float x, float y)Set the beginning of the next contour to the point (x,y).
设置终点setLastPoint(float dx, float dy)Sets the last point of the path.
连接直线lineTo(float x, float y)Add a line from the last point to the specified point (x,y).
闭合路径close()Close the current contour.
添加内容addArcaddCircleaddOvaladdPathaddRectaddRoundRectarcTo添加( 圆弧、 圆, 椭圆,路径,矩形, 圆角矩形, ) 到当前Path
是否为空isEmpty()Returns true if the path is empty (contains no lines or curves)
是否为矩形isRect(RectF rect)Returns true if the path specifies a rectangle.
替换路径set(Path src)Replace the contents of this with the contents of src.
偏移路径offsetOffset the path by (dx,dy)
重置路径reset()、rewind()Clear any lines and curves from the path, making it empty./Rewinds the path: clears any lines and curves from the path but keeps the internal data structure for faster reuse.
rXxx方法rCubicTorLineTorMoveTorQuadTo不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)
贝塞尔曲线quadTocubicT分别为二次和三次贝塞尔曲线的方法
矩阵操作transformTransform the points in this path by matrix
填充模式setFillTypetoggleInverseFillType()、isInverseFillType()、getFillType()设置、切换、判断和获取填充模式
计算边界computeBoundsCompute the bounds of the control points of the path, and write the answer into bounds.
布尔操作opSet this path to the result of applying the Op to the two specified paths
lineTo

首先先要说的是lineTo ,lineTo的方法如下:
lineTo(float x, float y)
Add a line from the last point to the specified point (x,y)
在上次的结束点和指定的点之间添加一条line,the last point是上次操作结束的点,如果没有上次结束的点呢,额,那就默认为坐标原点。
现在测试一下:

 int mWidth = getWidth();
int mHeight = getHeight();
canvas.translate(mWidth/2,mHeight/2);  //坐标移动到屏幕中心
Path path=new Path();       //创建Path
path.lineTo(200,200);
path.lineTo(200,-200);
canvas.drawPath(path,mPaint2);  //绘制Path

Image.png

在例子中,我们调用了两次lineTo,第一次调用时,因为之前没有调用过,所以默认点是坐标原点,第二次调用时,因为上次调用的结束点是(200,200),所以这次lineTo是(200,200)到(200,-200)之间的连线。

moveTo 和 setLastPoint:

moveTo(float x, float y) :Set the beginning of the next contour to the point (x,y).
setLastPoint(float dx, float dy):Sets the last point of the path
这两个方法看起来比较类似,其实是有很大不同的,如下表所示:

方法名简介是否影响之前的操作是否影响之后操作
moveTo(float x, float y)设置下次Path的起点
setLastPoint(float dx, float dy)设置上次操作最后一个点的位置

直接上代码:

canvas.translate(mWidth / 2, mHeight / 2);
Path path = new Path();
path.lineTo(200,200);
path.moveTo(200,0);
path.lineTo(200,-200);
canvas.drawPath(path,mPaint2);

Image.png

moveTo只改变下次操作的起点,在执行完第一次LineTo的时候,本来的默认点位置是(200,200),但是moveTo将其改变成为了(200,0),所以在第二次调用lineTo的时候就是连接(200,0) 到 (200,-200) 之间的直线。
- 下面是setLastPoint

canvas.translate(mWidth/2,mHeight/2);
Path path=new Path();
 path.lineTo(200,200);
 canvas.drawPoint(200,200,mPaint2);
 path.setLastPoint(200,100);
 path.lineTo(200,-200);
 canvas.drawPath(path,mPaint2);

setLastPoint是重置上一次操作的最后一个点,在执行完第一次的lineTo的时候,最后一个点是(200,200),而setLastPoint更改最后一个点为(200,100),所以在实际执行的时候,第一次的lineTo就不是从原点到(200,200)的连线了,而变成了从原点到C(200,100)之间的连线了。

在执行完第一次lineTo和setLastPoint后,最后一个点的位置是(200,100),所以在第二次调用lineTo的时候就是(200,100) 到 (200,-200) 之间的连线。

Image.png

close

close():Close the current contour
close方法用于连接当前最后一个点和最初的一个点(如果两个点不重合的话),最终形成一个封闭的图形。

canvas.translate(mWidth/2,mHeight/2);
Path path=new Path();
path.lineTo(200,200); path.lineTo(200,-200);
path.close();
canvas.drawPath(path,mPaint2);

Image.png
注意:close的作用是封闭路径,与连接当前最后一个点和第一个点并不等价。如果连接了最后一个点和第一个点仍然无法形成封闭图形,则close什么 也不做。

addXXX和arcTo

这次方法主要是在Path中添加基本图形,重点区分addArc与arcTo。
- 添加基本形状
1.添加圆形
addCircle(float x, float y, float radius, Path.Direction dir)
2.添加椭圆
addOval(RectF oval, Path.Direction dir)
addOval(float left, float top, float right, float bottom, Path.Direction dir)
3.添加矩形
addRect(RectF rect, Path.Direction dir)
addRect(float left, float top, float right, float bottom, Path.Direction dir)
4.添加圆角矩形
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)
可以看到,上述方法都有一个参数, Path.Direction dir,具体是做什么的呢
Direction的意思是 方向,趋势。 点进去看一下会发现Direction是一个枚举(Enum)类型,里面只有两个枚举常量,如下:

类型解释说明
CWclockwise顺时针
CCWcounter-clockwise逆时针
addPath

addPath(Path src) :Add a copy of src to the path
addPath(Path src, float dx, float dy):Add a copy of src to the path, offset by (dx,dy)
addPath(Path src, Matrix matrix):Add a copy of src to the path, transformed by matrix
addPath方法很明了,就是把两个Path合并为一个
第二个方法是将src平移后再合并在一起
第三个方法是将src进行Matrix变换后再合并到一起

 canvas.translate(mWidth/2,mHeight/2);
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);
canvas.drawPath(path,mPaint2);

Image.png

addArc与arcTo

addArc(RectF oval, float startAngle, float sweepAngle)— Add the specified arc to the path as a new contour.
addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle)—Add the specified arc to the path as a new contour
arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)—Append the specified arc to the path as a new contour.
arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)–Append the specified arc to the path as a new contour.
arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)—Append the specified arc to the path as a new contour

方法名作用区别
addArc添加一个圆弧到path直接添加一个圆弧到path
arcTo添加一个圆弧到path如果圆弧的起点和上次最后一个坐标点不同,就连接两个点

另外,可以看到arcTo方法最后一个参数是个boolean类型的,forceMoveTo,有什么作用呢

forceMoveTo含义
true将最后一个点移动到圆弧起点,即不连接最后一个点与圆弧起点
false不移动,而是连接最后一个点与圆弧起点

addArc

canvas.translate(mWidth/2,mHeight/2);
Path path=new Path();
path.lineTo(100,100);
RectF oval=new RectF(0,0,300,300);
path.addArc(oval,0,270);
canvas.drawPath(path,mPaint2);

Paste_Image.png
arcTo

canvas.translate(mWidth/2,mHeight/2);
Path path=new Path();
path.lineTo(100,100);
RectF oval=new RectF(0,0,300,300);
path.arcTo(oval,0,270);
canvas.drawPath(path,mPaint2);

Paste_Image.png

isEmpty、 isRect、isConvex、 set 和 offset
  • isEmpty()–Returns true if the path is empty (contains no lines or curves)
    主要是判断path是否为空
  • isRect(RectF rect):Returns true if the path specifies a rectangle.
    判断path是否是一个矩形
  • set(Path src):Replace the contents of this with the contents of src
    将新的path赋值到就得path
  • offset(float dx, float dy)
  • offset(float dx, float dy, Path dst)
    将path进行平移
    可以看到第二个方法多了一个dst参数,有什么不同呢
dst状态效果
dst不为空将当前path平移后的状态存入dst中,不会影响当前path
dst为空(null)平移将作用于当前path,相当于第一种方法
canvas.translate(mWidth/2,mHeight/2);
Path path=new Path();
path.addCircle(0,0,100,Path.Direction.CW);
Path dst=new Path();
 path.offset(300,0,dst);
canvas.drawPath(path,mPaint2);
path.offset(300,0);
canvas.drawPath(path,mPaint2);

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/3897939-1bde4442ed698893.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300
)
代码下载地址
https://github.com/baojie0327/ViewAndGroup

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值