Path主要用于绘制复杂的图形轮廓,比如折线,圆弧以及各种复杂图案
方法列表:
reset()
lineTo(float x, float y)
moveTo(float x, float y)
close()
path.addArc(oval, startAngle, sweepAngle)
arcTo(RectF oval, float startAngle, float sweepAngle)
quadTo(float x1, float y1, float x2, float y2)
addCircle(float x, float y, float radius, Direction dir)
addOval(RectF oval, Path.Direction dir)
addPath(Path src, float dx, float dy)
Paint初始化操作:
在处理path之前,我们首先对paint做一些初始化操作:
Paint paint = new Paint(); paint.setColor(Color.RED); //设置画笔宽度 paint.setStrokeWidth(3); //消除锯齿 paint.setAntiAlias(true); //设置镂空(方便查看效果) paint.setStyle(Style.STROKE);
path中从最基本的moveTo(float x, float y),lineTo(float x, float y),reset()及close()方法入手
reset()方法:
reset()清除path设置的所有属性
lineTo(float x, float y)方法:
lineTo(float x, float y)方法用于从当前轮廓点绘制一条线段到x,y点:
从原点开始绘制一条折线,代码如下:
Path path = new Path(); path.lineTo(100,100); path.lineTo(100, 200); path.lineTo(150, 250); canvas.drawPath(path, paint);
上图中没有指定初始轮廓点,默认从0,0点开始
moveTo(float x, float y)方法:
path的moveTo方法将起始轮廓点移至x,y坐标点,默认情况为0,0点
使用moveTo设置轮廓点:代码如下:
Path path = new Path();
path.moveTo(20, 200); path.lineTo(50, 200); path.lineTo(100, 300); path.lineTo(200, 350); canvas.drawPath(path, paint);
效果图如下:
上图使用moveTo改变path绘制起始顶点效果
close()方法:
回到初始点形成封闭的曲线
Path path = new Path();
path.moveTo(20, 200); path.lineTo(50, 200); path.lineTo(100, 300); path.lineTo(200, 350); path.close(); canvas.drawPath(path, paint);
效果图如下:
addArc(RectF oval, float startAngle, float sweepAngle)方法:
path.addArc方法用于绘制圆弧,这个圆弧取自RectF矩形的内接椭圆上的一部分,圆弧长度由后两个参数决定
startAngle:起始位置的角度值
sweepAngle:旋转的角度值
如图所示:其中矩形和两条直线是用来做对比
Rect rect = new Rect(100, 100, 300, 250); canvas.drawRect(rect, paint);
//绘制椭圆 canvas.drawOval(new RectF(rect), paint); canvas.drawLine(50, 175, 350, 175, paint); canvas.drawLine(200, 50, 200, 300, paint);
上图中标注了圆弧的0度起点和弧度增量方向为顺时针,那么当我们截取其中的0-90的长度圆弧对应的是右下角的四分之一圆弧长度:
Rect rect = new Rect(100, 100, 300, 250); canvas.drawRect(rect, paint); //canvas.drawOval(new RectF(rect), paint); canvas.drawLine(50, 175, 350, 175, paint); canvas.drawLine(200, 50, 200, 300, paint); path.reset();
// path.addArc(new RectF(rect), 30, 60); canvas.drawPath(path, paint);
arcTo(RectF oval, float startAngle, float sweepAngle)方法:
arcTo和addArc的区别:
1. addArc可以直接加入一段椭圆弧。使用arcTo还需要使用moveTo指定当前点的坐标。
2. arcTo如果当前点坐标和曲线的起始点不是同一个点的话,还会自动添加一条直线补齐路径。
Rect rect = new Rect(100, 100, 300, 250); canvas.drawRect(rect, paint); canvas.drawLine(50, 175, 350, 175, paint); canvas.drawLine(200, 50, 200, 300, paint); Path path = new Path(); path.moveTo(0, 0); path.arcTo(new RectF(rect), 0, 90); //path.addArc(new RectF(rect), 0, 90); canvas.drawPath(path, paint);
效果图:
quadTo(float x1, float y1, float x2, float y2)方法:
以当前路径结束点为开始点,(x1,y1)为控制点,(x2,y2)为结束点画一条二次贝塞尔曲线(相关贝赛尔曲线请再做查询)
Path path = new Path();
path.moveTo(20, 50); path.lineTo(50, 200); path.quadTo(100, 200, 150, 250); canvas.drawPath(path, paint);
addCircle(float x, float y, float radius, Direction dir)方法:
使用path绘制圆形,xy为圆的圆心 radius为圆的半径,Direction 为绘制元的方向
Diection.CCW 逆时针方向
Diection.CW 顺时针方向
Path path = new Path();
path.reset(); path.addCircle(100, 100, 50, Direction.CW); canvas.drawPath(path, paint);
addOval(RectF oval, Path.Direction dir)方法:
绘制椭圆,同上绘制圆的方法
addPath(Path src, float dx, float dy)方法:
在已有的Path上通过平移创建新的path:
Path path = new Path(); path.lineTo(100,100); path.lineTo(100, 200); path.lineTo(150, 250);
canvas.drawPath(path, paint); path.addPath(path, 100, 0); canvas.drawPath(path, paint);
关于path的一些路径特效下一章给出
玩过自定义View的小伙伴都知道,在View的绘制过程中,有一个类叫做Path,Path可以帮助我们实现很多自定义形状的View,特别是配合xfermode属性来使用的时候。OK,那我们今天就来看看Path中那几个常用的API。
1.moveTo
moveTo表示将绘制点移动到某一个坐标处,该方法并不会进行绘制,主要是用来移动画笔。默认情况下起始坐标位于(0,0)点,我们可以手动调整默认位置。
2.lineTo
lineTo表示绘制一条直线,参数表示目标坐标如下:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- Path path = new Path();
- path.lineTo(getResources().getDimensionPixelSize(R.dimen.dot1x),
- getResources().getDimensionPixelSize(R.dimen.dot1x));
- canvas.drawPath(path, paint);
- }
显示效果如下:
默认情况下,起始点为(0,0)点,如果我用moveTo将起始点坐标移至(0,150),代码如下:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- Path path = new Path();
- path.moveTo(0,getResources().getDimensionPixelSize(R.dimen.dot1x));
- path.lineTo(getResources().getDimensionPixelSize(R.dimen.dot1x),
- getResources().getDimensionPixelSize(R.dimen.dot1x));
- canvas.drawPath(path, paint);
- }
3.quadTo
quadTo可以用来绘制一个带控制点的曲线,说白了,其实就是贝塞尔曲线。如下:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- Path path = new Path();
- path.moveTo(0, 300);
- path.quadTo(150, 0, 300, 300);
- canvas.drawPath(path, paint);
- }
前两个参数表示控制点的坐标,后两个参数表示结束点的坐标:
4.cubicTo
cubicTo可以用来绘制具有两个控制点的贝塞尔曲线,代码如下:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- Path path = new Path();
- path.moveTo(300, 0);
- path.cubicTo(0, 150, 300, 450, 0, 600);
- canvas.drawPath(path, paint);
- }
前两个参数表示第一个控制点的坐标,第三四个参数表示第二个控制点的坐标,第五六个参数表示最终的坐标点,显示效果如下:
5.arcTo
artTo用来绘制一段圆弧,实际上是截取圆或者椭圆的一部分,比如下面一段代码:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- Path path = new Path();
- RectF oval = new RectF(0, 0, 300, 300);
- path.arcTo(oval, 0, 90);
- canvas.drawPath(path, paint);
- }
显示效果如下:
该方法接收三个参数,第一个表示弧形所在的矩形,如果矩形为正方形,则画出的弧形为圆的一部分,如果矩形宽高不等,画出的弧形为椭圆的一部分,第二个参数表示绘制的起点位置,0度为钟表三点位置,第三个参数表示绘制的度数。看下面一段代码:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- Path path = new Path();
- RectF oval = new RectF(0, 0, 600, 300);
- path.arcTo(oval, 0, 90);
- canvas.drawPath(path, paint);
- }
显示效果如下:
如上则是椭圆的一部分。
arcTo方法还有一个重载的方法,即接收四个参数,最后一个参数表示是否将弧形的起点与上一个图形的终点连接起来,true表示不连接,false表示连接,默认为false,如下一段代码:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- Path path = new Path();
- RectF oval = new RectF(0, 0, 600, 300);
- path.arcTo(oval, 0, 90);
- RectF oval2 = new RectF(0, 400, 300, 700);
- path.arcTo(oval2, 90, 180);
- canvas.drawPath(path, paint);
- }
显示效果如下:
如果我给第二条线再添加一个参数true,如下:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- Path path = new Path();
- path.lineTo(150, 150);
- RectF oval2 = new RectF(0, 200, 300, 500);
- path.arcTo(oval2, 0, 180, true);
- canvas.drawPath(path, paint);
- }
显示效果如下:
这里有个坑,一定要运行起来才有效果,编译之后预览看到的效果是错的。囧了个囧。。。。。
6.addArc、addRoundRect、addOval、addRect、addCircle
addArc,添加一个圆弧到路径中,这个圆弧实为圆或者椭圆的一部分,如下一段代码:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- Path path = new Path();
- RectF oval = new RectF(0, 200, 300, 500);
- path.addArc(oval, 0, 180);
- canvas.drawPath(path, paint);
- }
效果如下:
后面几种效果我一起来展示,代码如下:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- Path path = new Path();
- RectF oval = new RectF(50, 50, 150, 150);
- path.addRoundRect(oval,25,25, Path.Direction.CCW);
- RectF oval2 = new RectF(50, 200, 250, 300);
- path.addOval(oval2, Path.Direction.CCW);
- RectF oval3 = new RectF(50, 350, 150, 450);
- path.addRect(oval3, Path.Direction.CCW);
- path.addCircle(100, 550, 50, Path.Direction.CCW);
- canvas.drawPath(path, paint);
- }
显示效果如下:
Direction参数表示方向,其中CW代表顺时针,CCW代表逆时针。
7.Path.Op
Path中还有一个好用的Op属性,这个属性有点类似于Paint中的xfermode属性,可以用来组合两个Path。用法有如下几种:
7.1Path.Op.DIFFERENCE
Path.Op.DIFFERENCE表示从path中去除path2的部分,保留path的部分。如下案例:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- Path path = new Path();
- Path path2 = new Path();
- path.addCircle(200, 200, 100, Path.Direction.CCW);
- path2.addRect(200, 200, 300, 300, Path.Direction.CCW);
- path.op(path2, Path.Op.DIFFERENCE);
- canvas.drawPath(path, paint);
- }
显示效果如下:
7.2Path.Op.INTERSECT
Path.Op.INTERSECT表示取path和path2相交的部分显示出来,如下:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- Path path = new Path();
- Path path2 = new Path();
- path.addCircle(200, 200, 100, Path.Direction.CCW);
- path2.addRect(200, 200, 300, 300, Path.Direction.CCW);
- path.op(path2, Path.Op.INTERSECT);
- canvas.drawPath(path, paint);
- }
显示效果如下:
7.3Path.Op.REVERSE_DIFFERENCE
Path.Op.REVERSE_DIFFERENCE表示除去path的部分,只显示path2的部分,如下:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- Path path = new Path();
- Path path2 = new Path();
- path.addCircle(200, 200, 100, Path.Direction.CCW);
- path2.addRect(200, 200, 300, 300, Path.Direction.CCW);
- path.op(path2, Path.Op.REVERSE_DIFFERENCE);
- canvas.drawPath(path, paint);
- }
显示效果如下:
7.4Path.Op.UNION
Path.Op.UNION表示path和path2的部分都要显示出来,如下:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- Path path = new Path();
- Path path2 = new Path();
- path.addCircle(200, 200, 100, Path.Direction.CCW);
- path2.addRect(200, 200, 300, 300, Path.Direction.CCW);
- path.op(path2, Path.Op.UNION);
- canvas.drawPath(path, paint);
- }
显示效果如下:
7.5Path.Op.XOR
Path.Op.XOR表示显示path和path2但是不包含二者的交集。如下:
[java] view plain copy print ?
- @Override
- protected void onDraw(Canvas canvas) {
- Path path = new Path();
- Path path2 = new Path();
- path.addCircle(200, 200, 100, Path.Direction.CCW);
- path2.addRect(200, 200, 300, 300, Path.Direction.CCW);
- path.op(path2, Path.Op.XOR);
- canvas.drawPath(path, paint);
- }
显示效果如下:
OK,以上就是对Path类的一个简单介绍。
以上。