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);
效果图如下: