Flutter是Google的UI框架,所以绘制也秉承了Android的那套东西,坐标起点是从左上角开始的,API也非常相似,对Android开发者特别的友好。
CustomPaint
const CustomPaint({ Key? key, this.painter, this.foregroundPainter, this.size = Size.zero, this.isComplex = false, this.willChange = false, Widget? child, })
参数说明
painter
:在child之前绘制。绘制背影,child在上面。
foregroundPainter
:在child之后才绘制。绘制前景,在child上。
size
: 绘制画布的大小,默认为Size.zero,也就是0。不设置child时,CustomPainter会以这个Size进行绘制。当设置了child之后,size会被忽略,CustomPainter会使用child的size进行绘制。如果size和child的size都没有设置,那会根据CustomPaint的父widget的size进行绘制。如果3个都不设置,那size为Size.zero。
CustomPainter
/// Creates a custom painter. /// /// The painter will repaint whenever `repaint` notifies its listeners. const CustomPainter({ Listenable? repaint }) : _repaint = repaint;
repaint:提高性能,避免不必要的重绘。如果传入了,每次重绘时不会重新创建画布来绘制。每次都是同一个CustomPainter实例在触发paint方法。一般在频繁绘制时使用。
绘制
void paint(Canvas canvas, Size size)
canvas的坐标原点(0,0)不是基于屏幕左上角,而是基于父Widget的左上角。
一般我们需要根据size来绘制,如果不依赖size,可能会超出父Widget本身的大小。
样式
通过Painter
设置绘制的样式。
Paint _paint = Paint() /// 设置画笔颜色 ..color = Colors.blue /// 画笔宽度 ..strokeWidth = 2 /// 绘制形状和路径的样式。stroke只是线,fill会填充路径。默认为fill. ..style = PaintingStyle.stroke;
画直线
/// 从父widget左上角开始,画一条长度为100的直线 canvas.drawLine(Offset(0,0), Offset(100,100), _paint);
画点
canvas.drawPoints(PointMode.polygon,points,_paint);
将点连起来,可以用来画直线或折线。
canvas.drawPoints(PointMode.points,points,_paint);
矩形
/// 直角矩形 canvas.drawRect(); ///圆角矩形 canvas.drawRRect(); //同时绘制2个矩形,一个外框,一个内框。 canvas.drawDRRect();
弧形
void drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint)
- rect:弧形所在的矩形。
- startAngle:弧的起始点。0是矩形的右侧垂直中心。
- sweepAngle:孤的长度。
- useCenter:是否闭合路径。跟Photoshop中闭合路径效果一样。
注意:
参数中的startAngle和sweepAngle代表的不是角度,而是弧度。
第一次用的时候以为和Android中一样,用0到360度来画。
我们可以把弧度理解为周长,想画半圈就是pi,4分之一圈就是pi/2,以此类推。
狐度转角度: pi/180
示例:
/// 四分之一弧。 canvas.drawArc(Rect.fromLTRB(50, 100, 250, 200), 0, pi/2, false, _paint); /// 半圆弧 canvas.drawArc(Rect.fromLTRB(50, 100, 250, 200), 0, pi, false, _paint); /// 闭合路径 canvas.drawArc(Rect.fromLTRB(50, 100, 250, 200), 0, pi, false, _paint);
画圆
drawCircle
:正圆
drawOval
:根据传入的Rect,画正圆和椭圆
/// 正圆 canvas.drawCircle(Offset(100, 100), 30, _paint); /// 也是正圆 canvas.drawOval(Rect.fromLTRB(0,0,100,100),_paint); /// 椭圆 canvas.drawOval(Rect.fromLTRB(0,0,100,100),_paint);
颜色
会将颜色应用到之前绘制的内容上,除了文字。
canvas.drawColor(Colors.red, BlendMode.color);
图片
canvas.drawImage(); canvas.drawImageNine(); canvas.drawImageRect(); canvas.drawPicture(); canvas.drawAtlas();
文字
绘制文字有2种方式。
canvas.drawParagraph(UI.ParagraphBuilder(UI.ParagraphStyle()).build(), Offset(100,100)); TextPainter.paint(canvas,offset);
路径
drawPath()
Path path = Path(); path.lineTo(100, 100); path.lineTo(200, 100); canvas.drawPath(path, _paint);
3D
canvas.drawVertices();