Flutter是Google的UI框架,所以绘制也秉承了Android的那套东西,坐标起点是从左上角开始的,API也非常相似,对Android开发者特别的友好。
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。
/// 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)
注意:
参数中的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);
canvas.drawVertices();