Path主要用于绘制复杂的图形轮廓,比如折线,圆弧以及各种复杂图案
方法列表:
reset()
lineTo(float x, float y)
moveTo(float x, float y)
close()
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);
效果图如下:
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);
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);
效果图:Path path = new Path();
path.moveTo(20, 50); path.lineTo(50, 200); path.quadTo(100, 200, 150, 250); canvas.drawPath(path, paint);
使用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表示绘制一条直线,参数表示目标坐标如下:
- @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),代码如下:
- @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可以用来绘制一个带控制点的曲线,说白了,其实就是贝塞尔曲线。如下:
- @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可以用来绘制具有两个控制点的贝塞尔曲线,代码如下:
- @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用来绘制一段圆弧,实际上是截取圆或者椭圆的一部分,比如下面一段代码:
- @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度为钟表三点位置,第三个参数表示绘制的度数。看下面一段代码:
- @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,如下一段代码:
- @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,如下:
- @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,添加一个圆弧到路径中,这个圆弧实为圆或者椭圆的一部分,如下一段代码:
- @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);
- }
效果如下:
后面几种效果我一起来展示,代码如下:
- @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的部分。如下案例:
- @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相交的部分显示出来,如下:
- @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的部分,如下:
- @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的部分都要显示出来,如下:
- @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但是不包含二者的交集。如下:
- @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类的一个简单介绍。
以上。