Android Path类详解

来源:互联网 发布:热血传奇王者辅助源码 编辑:程序博客网 时间:2024/05/17 21:20

Path常用方法

方法作用备注moveTo移动起点移动下一次操作的起点位置lineTo连接直线连接上一个点到当前点之间的直线setLastPoint设置终点重置最后一个点的位置close闭合路劲从最后一个点连接最初的一个点,形成一个闭合区域addRect添加矩形添加矩形到当前PathaddRoundRect添加圆角矩形添加圆角矩形到当前PathaddOval添加椭圆添加椭圆到当前PathaddCircle添加圆添加圆到当前PathaddPah添加路劲添加路劲到当前PathaddArc添加圆弧添加圆弧到当前PatharcTo圆弧绘制圆弧,注意和addArc的区别isEmpty是否为空判定Path是否为空isRect是否为矩形判定Path是否是一个矩形set替换路劲用新的路劲替换当前路劲的所有内容offset偏移路劲对当前的路劲进行偏移quadTo贝塞尔曲线二次贝塞尔曲线的方法cubicTo贝塞尔曲线三次贝塞尔曲线的方法rMoveTo,rlineTo,rQuadTo,rCubicTorXxx方法不带r的方法是基于原点坐标系(偏移量),带r的基于当前点坐标系(偏移量)op布尔操作对两个Path进行布尔运算(交集,并集)等操作setFillType填充模式设置Path的填充模式getFillType填充模式获取Path的填充isInverseFillType是否逆填充判断是否是逆填充模式toggleInverseFillType相反模式切换相反的填充模式getFillType填充模式获取Path的填充incReserve提示方法提示Path还有多少个点等待加入computeBounds计算边界计算Path的路劲reset,rewind重置路劲清除Path中的内容(reset相当于new Path , rewind 会保留Path的数据结构)transform矩阵操作矩阵变换

Path方法使用详解

使用Path不仅可以绘制简单的图形(如圆形,矩形,直线等),也可以绘制复杂一些的图形(如正多边形,五角星等),还有绘制裁剪和绘制文本都会用到Path。由于方法比较多,我这里分组来讲下。

moveTo , lineTo , setLastPoint , close

先创建画笔:

        paint = new Paint();        paint.setAntiAlias(true);        paint.setStyle(Paint.Style.STROKE);        paint.setStrokeWidth(10);        paint.setColor(Color.parseColor("#FF0000"));

注意paint.setStyle(Paint.Style.FILL);,设置画笔为实心。一些线条将在画布上看不见。

1、lineTo

首先我们来看看lineTo,如果你直接moveTo 将看不出效果。

        Path path = new Path();        path.lineTo(200,200);        path.lineTo(400,0);        canvas.drawPath(path,paint);

path

为了方便大家好观察坐标的变化,我在屏幕上画出了网格,每块网格的宽高都是100。由于第一次之前没有过操作,所以默认点就是原点(屏幕左上角),第一次lineTo就是坐标原点到(200,200)之间的直线。第二次lineTo就是上一次结束点位置(200,200)到(400,0)点之间的直线。

方法预览:

moveTo(float x, float y) setLastPoint(float dx, float dy)

这两个方法在作用上有相似之处,却是两个不同的东西,具体参考下表:

方法名作用是否影响之前的操作是否影响之后的操作moveTo移动下一次操作的起点位置否是setLastPoint改变上一次操作点的位置是是

来看看下面的例子:

        Path path = new Path();        path.lineTo(200, 200);        path.moveTo(300,300);        path.lineTo(400, 0);        canvas.drawPath(path, paint);

效果图:

path

        Path path = new Path();        path.lineTo(200, 200);        path.setLastPoint(300,100);        path.lineTo(400, 0);        canvas.drawPath(path, paint);

效果图:

path

当我们绘制线条之前,调用moveTo 和 setLastPoint效果是一样的,都是对坐标原点(0,0)进行操作。setLastPoint是重置上一次操作的最后一点,在执行完第一次lineTo的时候,最后一个点就是(200,200),setLastPoint更改(200,200)为(300,100),所以在执行的时候就是(300,100)到(400, 0)之间的连线了。

3、close

方法预览

public void close()

close方法连接最后一个点和最初一个点(如果两个点不重合)形成一个闭合的图形。

        path.moveTo(100,100);        path.lineTo(500,100);        path.lineTo(300,400);        path.close();        canvas.drawPath(path, paint);

效果图:

path

上图中可以看到lineTo(500,100)直线和lineTo(300,400)直线,而close方法就是连接(300,400),(100,100)两点,形成一个闭合的区域。

注意:close的作用的封闭路径,如果连接最后一个点和最初一个点任然无法形成闭合的区域,那么close什么也不做。

quadTo,cubicTo

二次贝塞尔曲线以及三次贝塞尔曲线。

1、quadTo

方法预览

public void quadTo(float x1, float y1, float x2, float y2)

quadTo方法其中 (x1,y1) 为控制点,(x2,y2)为结束点。

        path.moveTo(100,400);        path.quadTo(300, 100, 400, 400);        canvas.drawPath(path, paint);

效果图:

path

2、cubicTo

方法预览:

public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)

cubicTo方法比quadTo方法多了一个点坐标,那么其中(x1,y1) 为控制点,(x2,y2)为控制点,(x3,y3) 为结束点。

        path.moveTo(100, 400);        path.cubicTo(100, 400, 300, 100, 400, 400);        canvas.drawPath(path, paint);

绘制的图形和上面的quadTo绘制的图形是一样的。我们去掉moveTo来看看运行的效果图:

path

如果你想了解贝塞尔曲线公式,请链接这里

addXxx和arcTo

主要是向Path中添加基本图形以及区分addArcarcTo

1、添加基本图形

方法预览:

//圆形addCircle(float x, float 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)

我们仔细观察上面的方法,在最后都有一个Path.Direction,这是个什么东东呢?Direction的意思是方向,指导,趋势。点进去跟一下你会发现Direction是一个枚举类型(Enum)分别有CW(顺时针),CCW(逆时针)两个常量。那么它的作用主要有以下两点:

序号作用1在添加图形时确定闭合顺序(各个点的记录顺序)2对自相交图形的渲染结果有影响

我们先来看看闭合顺序的问题,添加一个矩形看看:

        path.addRect(100, 200, 500, 400, Path.Direction.CW);        canvas.drawPath(path, paint);

path

我将上面的代码CW改成CCW再运行一次,结果一模一样,尼玛区别在哪里啊。稍安勿躁,想看到区别就要用到setLastPoint(重置最后一个点的坐标)。我们来这样变变代码:

        path.addRect(100, 200, 500, 400, Path.Direction.CW);        path.setLastPoint(200,400);        canvas.drawPath(path, paint);

效果立马现行:

path

为什么图形会发生奇怪的变化呢。我们先来分析一下,绘制一个矩形至少需要对角线的两个点,根据这两个点计算出四条边然后把四条边按照顺序连接起来。上图的起始坐标是(100,200)按着顺时针的方向连接(500,200),(500,400),(100,400)最后连接(100,200)形成一个矩形。setLastPoint是重置上一个操作点坐标及改变(100,400)为(200,400),所以出现了上图的效果。

接下来我们看看逆时针的情况:

        path.addRect(100, 200, 500, 400, Path.Direction.CCW);        path.setLastPoint(400,300);        canvas.drawPath(path, paint);

效果图:

path

我们理清楚了闭合的问题,相交问题与设置填充模式有关。

我以addCircle方法来讲解添加图形,并不会逐一讲解。

        path.addCircle(300,300,200, Path.Direction.CW);        canvas.drawPath(path, paint);

path

绘制圆形,(300,300)点表示圆心坐标,200 表示半径长度。

2、addPath

方法预览:

public void addPath(Path src)public void addPath(Path src, float dx, float dy)public void addPath(Path src, Matrix matrix)

addPath方法就是将两个路径合并到一起。第二个方法的dx,dy指的是偏移量,第三个方法是添加到当前path之前先使用Matrix进行变换。来看看下面例子:

        Path path = new Path();        path.addRect(100,100,400,300, Path.Direction.CW);        Path src=new Path();        src.addCircle(300,300,100, Path.Direction.CW);        path.addPath(src,0,100);        canvas.drawPath(path, paint);

效果图:

path

3、addArc与arcTo

方法预览:

addArc(RectF oval, float startAngle, float sweepAngle)addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle)arcTo(RectF oval, float startAngle, float sweepAngle)arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)

从方法名字上面看,这两个方法都是与圆弧有关,那么他们之间肯定是有区别的:

名称作用区别addArc添加一个圆弧到Path直接添加一个圆弧到path中,和上一次操作点无关arcTo添加一个圆弧到Path添加一个圆弧到path中,如果圆弧的起点和上次操作点坐标不同就连接两个点

startAngle表示开始圆弧度数(0度与X轴方向对齐,顺时针移动,弧度增大)。

注意:sweepAngle表示运动了多少弧度,并不是结束弧度。

forceMoveTo表示“是否强制使用moveTo”,也就是说是否使用moveTo将上一次操作点移动到圆弧的起点坐标。默认是false。

forceMoveTo含义true将最后一个点移动到圆弧起点,即不连接最后一个点与圆弧起点false不移动,而是连接最后一个点与圆弧起点(注意之前没有操作的话,不会连接原点)

示例:

        path.lineTo(200, 200);        RectF rectF = new RectF(100, 100, 400, 400);        path.arcTo(rectF, 0, 270, true);        // path.addArc(rectF,0,270);和上面一句等价        canvas.drawPath(path, paint);

效果图:

path

我们把 path.arcTo(rectF, 0, 270, true);改成 path.arcTo(rectF, 0, 270, false);,来看看效果图:

path

从上面两张图可以看出明显的变化。

isEmpty、 isRect、 set 和 offset

isEmpty

判断path中是否包含内容。

        Path path = new Path();        Log.e("-----","----"+path.isEmpty());//-----: ----true        path.lineTo(100,100);        Log.e("-----","----"+path.isEmpty());//-----: ----false        canvas.drawPath(path, paint);

isRect

方法预览:

isRect(RectF rect)

判断path是否是一个矩形,如果是一个矩形的话,会将矩形的信息存放进参数rect中。

        Path path = new Path();        RectF rectF = new RectF();        rectF.left = 100;        rectF.top = 100;        rectF.right = 400;        rectF.bottom = 300;        path.addRect(rectF, Path.Direction.CW);        boolean isRect = path.isRect(rectF);        Log.e("-----","------"+isRect);//-----: ------true

set

方法预览:

public void set(Path src)

将新的path赋值到现有path。相当于运算符中的“=”,如a=b,把b赋值给a

还是一起来看个例子:

        Path path = new Path();        path.addRect(100,100,400,300, Path.Direction.CW);        Path src=new Path();        src.addCircle(300,200,100, Path.Direction.CW);        path.set(src);        canvas.drawPath(path, paint);

效果图:

path

offset

方法预览:

public void offset(float dx, float dy)public void offset(float dx, float dy, Path dst)

这个方法就是对Path进行一段平移,正方向和X轴,Y轴方向一致(如果dx为正数则向右平移,反之向左平移;如果dy为正则向下平移,反之向上平移)。我们看到第二个方法多了一个dst,这个又是一个什么玩意呢,其实参数das是存储平移后的path的。

用例子来说明一下:

        Path path = new Path();        path.addCircle(300, 200, 100, Path.Direction.CW);        Path dst = new Path();        dst.addCircle(500, 200, 200, Path.Direction.CW);        path.offset(-100, 100, dst);        canvas.drawPath(path, paint);

效果图:

path

从运行效果图可以看出,虽然我们在dst中添加了一个圆形,但是并没有表现出来,所以,当dst中存在内容时,dst中原有的内容会被清空,而存放平移后的path。

FillType

方法预览:

public void setFillType(Path.FillType ft)public Path.FillType getFillType()

setFillType方法中的参数Path.FillType为枚举类型:

FillType值含义FillType.WINDING取path所有所在区域 默认值FillType.EVEN_ODD取path所在并不相交区域FillType.INVERSE_WINDING取path所有未占区域FillType.INVERSE_EVEN_ODD取path未占或相交区域

path所在区域
path所在区域
path所在区域

setFillType

WINDING

        Path path = new Path();        path.addCircle(300,200,100, Path.Direction.CW);        path.addCircle(200,200,100, Path.Direction.CW);        path.setFillType(Path.FillType.WINDING);        canvas.drawPath(path, paint);

效果图:

path

EVEN_ODD

代码我就不贴了,直接上图(上mis):

path

INVERSE_WINDING

path

INVERSE_EVEN_ODD

path

isInverseFillType

是否是逆填充模式:WINDING 和 EVEN_ODD 返回false;
INVERSE_WINDING 和 INVERSE_EVEN_ODD 返回true;

toggleInverseFillType

切换相反的填充模式,如果填充模式为WINDING则填充模式为INVERSE_WINDING,反之为WINDING模式;如果填充模式为EVEN_ODD则填充模式为INVERSE_EVEN_ODD,反之为EVEN_ODD模式。

举个例子:

        Path path = new Path();        path.addCircle(300,200,100, Path.Direction.CW);        path.addCircle(200,200,100, Path.Direction.CW);        path.setFillType(Path.FillType.INVERSE_EVEN_ODD);        path.toggleInverseFillType();        canvas.drawPath(path, paint);

效果图和上面EVEN_ODD模式一模一样。

path

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小米4左键失灵怎么办 小米5s左键失灵怎么办 单击鼠标左键就会自动删除?怎么办 华为五s开不开机怎么办 荣耀8关不了机怎么办 三星s7左键失灵怎么办 华为mate7死机黑屏了怎么办 小米手机max黑屏打不开怎么办 小米max开不了机怎么办 小米6接听电话声音小怎么办 小米手机接听电话声音小怎么办 小米5听筒声音小怎么办 红米手机不能开机怎么办 小米5x升级失败怎么办 安卓手机打电话黑屏怎么办 来电话就出黑屏怎么办 oppo手机停留在开机界面怎么办 小米4c死机了怎么办 苹果手机拨打电话时黑屏怎么办 华为畅享6黑屏怎么办 手机拨号键盘变小了怎么办 小米5s手机黑屏打不开怎么办 小米5s黑屏只能开关机怎么办 手机拨号键没了怎么办 华为手机桌面拨号图标不见了怎么办 华为手机拨号图标不见了怎么办 小米4s屏幕显示黑屏怎么办 平板拨号键没了怎么办 华为手机拨号图标没了怎么办 华为荣耀手机进水了怎么办 华为畅享7黑屏怎么办 华为畅玩7x黑屏怎么办 华为手机打电话时黑屏怎么办 三星a8手机黑屏打不开怎么办 华为手机恢复出厂后黑屏怎么办 华为荣耀4c白屏怎么办 华为荣耀6手机信号不好怎么办 华为荣耀8手机音量小怎么办 无法激活触控id怎么办 魅蓝2卡顿怎么办 小米max2玩王者荣耀卡怎么办