Flutter中自繪組件是CustomPaint,它是一個widget。配合CustomPainter(畫筆),可以畫出任意想要的圖形。
CustomPaint構造函數如下:
const CustomPaint({ Key key, this.painter, ///背景畫筆,會展示在child后面 this.foregroundPainter, ///前景畫筆,展示在child前面 this.size = Size.zero, this.isComplex = false, this.willChange = false, Widget child, ///child不為空,size失效,自動和child保持一致;如果有child還想指定畫布大小,可以用SizedBox包裹CustomPaint實現。 })
CustomPainter是畫筆類,我們定義自己的畫筆時,需要繼承Custompainter,重寫paint方法即可(最好也重寫shouldRepaint方法,正確的使用該回調可以避免重繪開銷)。
Paint類是當在canvas上畫畫的時候使用的畫筆屬性,如顏色/填充樣式等等,一個自繪圖片上可能會需要很多畫筆畫很多圖形。如下代碼所示,針對每個圖形,定義不同的畫筆style進行繪制,實際的繪制是通過調用canvas.drawXXX實現的。
class MyPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { double eWidth = size.width / 15; double eHeight = size.height / 15; //畫棋盤背景 var paint = Paint() ..isAntiAlias = true ..style = PaintingStyle.fill //填充 ..color = Color(0x77cdb175); //背景為紙黃色 canvas.drawRect(Offset.zero & size, paint); //畫棋盤網格 paint ..style = PaintingStyle.stroke //線 ..color = Colors.black87 ..strokeWidth = 1.0; for (int i = 0; i <= 15; ++i) { double dy = eHeight * i; canvas.drawLine(Offset(0, dy), Offset(size.width, dy), paint); } for (int i = 0; i <= 15; ++i) { double dx = eWidth * i; canvas.drawLine(Offset(dx, 0), Offset(dx, size.height), paint); } //畫一個黑子 paint ..style = PaintingStyle.fill ..color = Colors.black; canvas.drawCircle( Offset(size.width / 2 - eWidth / 2, size.height / 2 - eHeight / 2), min(eWidth / 2, eHeight / 2) - 2, paint, ); //畫一個白子 paint.color = Colors.white; canvas.drawCircle( Offset(size.width / 2 + eWidth / 2, size.height / 2 - eHeight / 2), min(eWidth / 2, eHeight / 2) - 2, paint, ); } //在實際場景中正確利用此回調可以避免重繪開銷,本示例我們簡單的返回true @override bool shouldRepaint(CustomPainter oldDelegate) => true; }
上面定義了我們自己的CustomPainter,只需要把它放入CustomPaint就行了。
class CustomPaintRoute extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: CustomPaint( size: Size(300, 300), //指定畫布大小 painter: MyPainter(), ), ); } }