用户登录
用户注册

分享至

Android 自定义View Path

  • 作者: 薄荷浓
  • 来源: 51数据库
  • 2021-07-28

Path 的概念:

Path类封装由直线段,二次曲线和三次曲线组成的复合(多个轮廓)几何路径。可以使用canvas.drawPath(path,paint)对其进行填充或描边绘制(基于Paint的Style),也可以用于剪切或在路径上绘制文本

Path 的使用也就是上一篇canvas 里面没有说的drawPath方法

(1)lineTo、rLineTo? 绘制线? (注意很多方法都有不带r与带r 我也写了2边它们的区别,不带r的)

(2)moveTo、rMoveTo 修改起始点位置

(3)setLastPoint 修改最后点的位置(假如竖线的长度本想想画400长度结果为了600的长度,这个时候可以使用该方法修改)

?下面说一些添加图形的方法在说之前先说下Path.Direction方法

Path.Direction.CW 顺时针绘制,Path.Direction.CCW 逆时针绘制 ,了解这个在看下面的常规图形方法(为了更好的理解可以看案例9 的效果图以及代码给出顺时针和逆时针的效果图)

? (4)? addRect 绘制矩形(长方形和正方形)

? (5)? addCircle 绘制圆形

(6)addOval 绘制椭圆

(7)addRoundRect 绘制圆角矩形

(8)addArc 绘制圆弧

(9)drawTextOnPath??设置决定了文本沿着路径的起始位置

(10)close? 闭合path

(11)setFillType?设置路径的填充类型

? (12)?quadTo 和cubicTo 贝塞尔曲线 (这个之前项目中写过水滴的效果等有空在整理下)

1 lineTo、rLineTo? 绘制线? (注意很多方法都有不带r与带r 我也写了2边它们的区别,不带r的)

 paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        path.lineTo(200, 400);
        // 绘制线
        canvas.drawPath(path, paint);

效果图

在绘制一些折线如下

  paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        path.lineTo(200, 400);
        path.lineTo(300, 100);
        path.lineTo(400, 400);
        path.lineTo(500, 50);
        path.lineTo(600, 400);
        path.lineTo(700, 100);
        path.lineTo(800, 400);
        // 绘制线
        canvas.drawPath(path, paint);

效果图如下

2?moveTo、rMoveTo 修改起始点位置(由于lineTo 默认其实点为0.0 如果不想从默认点开始需要借助?moveTo、rMoveTo)

?下面会一条竖线代码如下

  paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        path.moveTo(200,200);
        path.lineTo(200, 400);
        // 绘制线
        canvas.drawPath(path, paint);

效果图

3?setLastPoint 修改最后点的位置(假如竖线的长度本想想画400长度结果为了600的长度,这个时候可以使用该方法修改)

     paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        path.moveTo(200,200);
        
        // 和path.lineTo(200, 400); 长度一样
        path.lineTo(200, 600);
        path.setLastPoint(200,400);

       

效果图如下

4? addRect 矩形

 paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        // 设置一个矩形
        path.addRect(100,200, 600, 500,Path.Direction.CW);
        // 绘制
        canvas.drawPath(path, paint);

或者

  paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        // 设置一个矩形
        RectF rect = new RectF();
        rect.left = 100;
        rect.top = 200;
        rect.right = 600;
        rect.bottom = 500;
        path.addRect(rect,Path.Direction.CW);
        // 绘制
        canvas.drawPath(path, paint);

?效果图如下

5?addCircle 圆形

  paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        // 设置一个圆
        path.addCircle(500, 500, 300, Path.Direction.CW);
        // 绘制
        canvas.drawPath(path, paint);

效果图如下

6?addOval 椭圆

  paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        // 设置一个圆
        path.addOval(100,200, 600, 500,Path.Direction.CW);
        // 绘制
        canvas.drawPath(path, paint);

或者

 paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        // 设置一个圆
        RectF rect = new RectF();
        rect.left = 100;
        rect.top = 200;
        rect.right = 600;
        rect.bottom = 500;
        path.addRect(rect, Path.Direction.CW);
        // 绘制
        canvas.drawPath(path, paint);

效果图如下

7

 paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        path.addRoundRect(100,200,600,500,100,200, Path.Direction.CW);
        // 绘制
        canvas.drawPath(path, paint);

?或者

 paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        // 设置一个圆
        RectF rect = new RectF();
        rect.left = 100;
        rect.top = 200;
        rect.right = 600;
        rect.bottom = 500;
        path.addRoundRect(rect,100,200, Path.Direction.CW);
        // 绘制
        canvas.drawPath(path, paint);

效果图如下:

8?addArc 绘制圆弧

 paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        path.addArc(100,200,600,500,0,270);
        // 绘制
        canvas.drawPath(path, paint);

或者

 paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);
        Path path = new Path();
        RectF rect = new RectF();
        rect.left = 100;
        rect.top = 200;
        rect.right = 600;
        rect.bottom = 500;
        path.addArc(rect, 0, 270);
        // 绘制
        canvas.drawPath(path, paint);

效果图如下:

?

9 drawTextOnPath??设置决定了文本沿着路径的起始位置

Path.Direction.CW代码如下

 paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setTextSize(100);
        paint.setStrokeWidth(5f);
        Path path = new Path();
        path.addCircle(500, 500, 400, Path.Direction.CW);
        canvas.drawTextOnPath("期待是心痛的根源,心不动,则不痛。", path, 0, 0, paint);
        // 绘制
        canvas.drawPath(path, paint);

效果图如下:

Path.Direction.CCW代码如下

paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setTextSize(100);
        paint.setStrokeWidth(5f);
        Path path = new Path();
        path.addCircle(500, 500, 400, Path.Direction.CCW);
        canvas.drawTextOnPath("期待是心痛的根源,心不动,则不痛。", path, 0, 0, paint);
        // 绘制
        canvas.drawPath(path, paint);

效果图如下

下面在绘制一个正方形的

 paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setTextSize(100);
        paint.setStrokeWidth(5f);
        Path path = new Path();
        RectF rect = new RectF();
        rect.left = 100;
        rect.top = 200;
        rect.right = 600;
        rect.bottom = 500;
        path.addRect(rect, Path.Direction.CW);
        canvas.drawTextOnPath("期待是心痛的根源,心不动,则不痛。", path, 0, 0, paint);
        // 绘制
        canvas.drawPath(path, paint);

效果图如下:

10 close 闭合

?现在画一个竖线和横线如下

  paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setTextSize(100);
        paint.setStrokeWidth(5f);
        Path path = new Path();
        path.moveTo(300, 300);
        path.lineTo(300, 700);
        path.lineTo(700, 700);
        // 绘制
        canvas.drawPath(path, paint);

xiaoguo图如下

使用闭合方法

 paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setTextSize(100);
        paint.setStrokeWidth(5f);
        Path path = new Path();
        path.moveTo(300, 300);
        path.lineTo(300, 700);
        path.lineTo(700, 700);
        path.close();
        // 绘制
        canvas.drawPath(path, paint);

效果图如下:

11?setFillType?设置路径的填充类型, (下面的基本没用过简单的了解下)

里面有四种类型?WINDING,EVEN_ODD,INVERSE_WINDING,INVERSE_EVEN_ODD

WINDING 是默认类型,指定“内部”由有符号边交叉的非零和计算

EVEN_ODD?指定“内部”由奇数个边交叉计算 ,---个人理解就是交叉本分

INVERSE_WINDING 与{@link#WINDING}相同,但绘制在路径外部,而不是内部,---个人理解就是绘制画图之外的区域

INVERSE_EVEN_ODD 与{@link#偶数奇数}相同,但绘制在路径外部,而不是内部--个人理解就是交叉也之外的区域

下面画2个有交叉的圆看看效果

11.1?WINDING (默认部分)

 paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setTextSize(100);
        paint.setStrokeWidth(5f);
        Path path = new Path();
        path.addCircle(500, 500, 300, Path.Direction.CW);
        path.addCircle(700, 700, 300, Path.Direction.CW);
        path.setFillType(Path.FillType.WINDING);
        // 绘制
        canvas.drawPath(path, paint);
效果图如下(感觉和不添加效果一样)

11.2?INVERSE_WINDING?

 paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.FILL);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setTextSize(100);
        paint.setStrokeWidth(5f);
        Path path = new Path();
        path.addCircle(500, 500, 300, Path.Direction.CW);
        path.addCircle(700, 700, 300, Path.Direction.CW);
        path.setFillType(Path.FillType.WINDING);
        // 绘制
        canvas.drawPath(path, paint);

效果图如下:

?

11.3?INVERSE_WINDING

  paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.FILL);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setTextSize(100);
        paint.setStrokeWidth(5f);
        Path path = new Path();
        path.addCircle(500, 500, 300, Path.Direction.CW);
        path.addCircle(700, 700, 300, Path.Direction.CW);
        path.setFillType(Path.FillType.INVERSE_WINDING);
        // 绘制
        canvas.drawPath(path, paint);

效果图如下:

11.4 INVERSE_EVEN_ODD

    paint.setAntiAlias(true);
        // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边,Paint.Style.FILL_AND_STROKE填充加描边  )
        paint.setStyle(Paint.Style.FILL);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setTextSize(100);
        paint.setStrokeWidth(5f);
        Path path = new Path();
        path.addCircle(500, 500, 300, Path.Direction.CW);
        path.addCircle(700, 700, 300, Path.Direction.CW);
        path.setFillType(Path.FillType.INVERSE_EVEN_ODD);
        // 绘制
        canvas.drawPath(path, paint);

效果图如下:

软件
前端设计
程序设计
Java相关