自定义viewAndroid知识Android开发

Android自定义控件(三 .0)Path的基本操作

2017-04-14  本文已影响74人  Jackson杰

前面http://www.jianshu.com/p/35765aa6f7d9 所讲的绘制的图形都是基本的简单图形,如矩形,员,圆弧等。如果对于一些复杂的图形(五角星,心形)的绘制,前面的绘图方法就无能为力了。而使用Path不仅可以绘制简单的图形,还能复制一些复杂的图形。
Google官网上Path的链接为:https://developer.android.google.cn/reference/android/graphics/Path.html
google官网上对path的解释为:

Path的相关方法
作用 相关方法 备注
移动起点 [moveTo](https://developer.android.google.cn/reference/android/graphics/Path.html#moveTo(float, float))(float x, float y) Set the beginning of the next contour to the point (x,y).
设置终点 [setLastPoint](https://developer.android.google.cn/reference/android/graphics/Path.html#setLastPoint(float, float))(float dx, float dy) Sets the last point of the path.
连接直线 [lineTo](https://developer.android.google.cn/reference/android/graphics/Path.html#lineTo(float, float))(float x, float y) Add a line from the last point to the specified point (x,y).
闭合路径 close() Close the current contour.
添加内容 [addArc](https://developer.android.google.cn/reference/android/graphics/Path.html#addArc(float, float, float, float, float, float))、[addCircle](https://developer.android.google.cn/reference/android/graphics/Path.html#addCircle(float, float, float, android.graphics.Path.Direction))、[addOval](https://developer.android.google.cn/reference/android/graphics/Path.html#addOval(android.graphics.RectF, android.graphics.Path.Direction))、[addPath](https://developer.android.google.cn/reference/android/graphics/Path.html#addPath(android.graphics.Path, android.graphics.Matrix))、[addRect](https://developer.android.google.cn/reference/android/graphics/Path.html#addRect(android.graphics.RectF, android.graphics.Path.Direction))、[addRoundRect](https://developer.android.google.cn/reference/android/graphics/Path.html#addRoundRect(android.graphics.RectF, float, float, android.graphics.Path.Direction))、[arcTo](https://developer.android.google.cn/reference/android/graphics/Path.html#arcTo(android.graphics.RectF, float, float, boolean)) 添加( 圆弧、 圆, 椭圆,路径,矩形, 圆角矩形, ) 到当前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.
偏移路径 [offset](https://developer.android.google.cn/reference/android/graphics/Path.html#offset(float, float)) Offset 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方法 [rCubicTo](https://developer.android.google.cn/reference/android/graphics/Path.html#rCubicTo(float, float, float, float, float, float))、[rLineTo](https://developer.android.google.cn/reference/android/graphics/Path.html#rLineTo(float, float))、[rMoveTo](https://developer.android.google.cn/reference/android/graphics/Path.html#rMoveTo(float, float))、[rQuadTo](https://developer.android.google.cn/reference/android/graphics/Path.html#rQuadTo(float, float, float, float)) 不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)
贝塞尔曲线 [quadTo](https://developer.android.google.cn/reference/android/graphics/Path.html#quadTo(float, float, float, float))、[cubicT](https://developer.android.google.cn/reference/android/graphics/Path.html#cubicTo(float, float, float, float, float, float)) 分别为二次和三次贝塞尔曲线的方法
矩阵操作 transform Transform the points in this path by matrix
填充模式 setFillTypetoggleInverseFillType()、isInverseFillType()、getFillType() 设置、切换、判断和获取填充模式
计算边界 [computeBounds](https://developer.android.google.cn/reference/android/graphics/Path.html#computeBounds(android.graphics.RectF, boolean)) Compute the bounds of the control points of the path, and write the answer into bounds.
布尔操作 [op](https://developer.android.google.cn/reference/android/graphics/Path.html#op(android.graphics.Path, android.graphics.Path, android.graphics.Path.Op)) Set this path to the result of applying the Op to the two specified paths
lineTo

首先先要说的是lineTo ,lineTo的方法如下:
[lineTo](https://developer.android.google.cn/reference/android/graphics/Path.html#lineTo(float, float))(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](https://developer.android.google.cn/reference/android/graphics/Path.html#moveTo(float, float))(float x, float y) :Set the beginning of the next contour to the point (x,y).
[setLastPoint](https://developer.android.google.cn/reference/android/graphics/Path.html#setLastPoint(float, float))(float dx, float dy):Sets the last point of the path
这两个方法看起来比较类似,其实是有很大不同的,如下表所示:

方法名 | 简介 | 是否影响之前的操作 | 是否影响之后操作
------------|---------|--------------|--------------|------------
[moveTo](https://developer.android.google.cn/reference/android/graphics/Path.html#moveTo(float, float))(float x, float y)|设置下次Path的起点|否|是
[setLastPoint](https://developer.android.google.cn/reference/android/graphics/Path.html#setLastPoint(float, float))(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) 之间的直线。

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。

类型 解释 说明
CW clockwise 顺时针
CCW counter-clockwise 逆时针
addPath

addPath(Path src) :Add a copy of src to the path
[addPath](https://developer.android.google.cn/reference/android/graphics/Path.html#addPath(android.graphics.Path, float, float))(Path src, float dx, float dy):Add a copy of src to the path, offset by (dx,dy)
[addPath](https://developer.android.google.cn/reference/android/graphics/Path.html#addPath(android.graphics.Path, android.graphics.Matrix))(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](https://developer.android.google.cn/reference/android/graphics/Path.html#addArc(android.graphics.RectF, float, float))(RectF oval, float startAngle, float sweepAngle)--- Add the specified arc to the path as a new contour.
[addArc](https://developer.android.google.cn/reference/android/graphics/Path.html#addArc(float, float, float, float, float, float))(float left, float top, float right, float bottom, float startAngle, float sweepAngle)---Add the specified arc to the path as a new contour
[arcTo](https://developer.android.google.cn/reference/android/graphics/Path.html#arcTo(android.graphics.RectF, float, float, boolean))(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)---Append the specified arc to the path as a new contour.
[arcTo](https://developer.android.google.cn/reference/android/graphics/Path.html#arcTo(float, float, float, float, float, float, boolean))(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](https://developer.android.google.cn/reference/android/graphics/Path.html#arcTo(android.graphics.RectF, float, float, boolean))(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
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
代码下载地址
https://github.com/baojie0327/ViewAndGroup
上一篇 下一篇

猜你喜欢

热点阅读