Flutter-自绘组件CustomPaint

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(),
      ),
    );
  }
}

 

posted @ 2020-10-12 15:59  NeoZy  阅读(868)  评论(0编辑  收藏  举报