在 Flutter 中自定义画笔 Painter

前言

今天我们将讨论定制 Painter,首先我们将看看什么时候使用定制 Painter,定制 Painter 是如何工作的,最后但并非最不重要的是,我们将看到一些 Flutter 定制 Painter 的项目。

原文 https://medium.com/nerd-for-tech/custom-painter-in-flutter-7d36af4dcabb

这意味着你不一定需要一个 widget 来在画布上绘制什么东西这样你就可以直接在画布上创建点,路径,弧线之类的东西。

所以想象一下一些 widget 或者一些想法一个标志或者一些你想要动画的东西一个完美的选项为一个自定义 Painter 好了,现在我们已经覆盖了你知道什么时候使用自定义 Painter。

正文

什么是定制 Paint?

Flutter SDK 中的 Custom Paint widget 允许您在画布上绘制不同的形状。它包含以下属性:

  • Painter: 在 child 画画之前,Painter 先画画。在这种情况下,有必要扩展定制 Painter。
  • Size: 这个自定义绘图器的 size 最初等于 Size.zero,这意味着如果没有定义子元素或者 size,它将不会出现。
  • Foreground Painter: 在 child 后面画画的 Painter。它也需要一个类,扩展类定制 Painter。
  • Child: 此 widget 树下的 widget 。

使用自定义绘图时有两种选择: 要么指定不带子属性的 size 属性,要么使用子属性为其提供 widget 。

扩展 extends CustomPainter

定制 Paint 工到底是怎么工作的?这是一个你可以用自定义 Painter 类扩展的类,你可以像使用其他 widget 一样使用它,但重要的是,周围 widget 的大小和高度将作为画布大小传递给自定义 Painter。

我们马上就会知道这意味着什么,自定义 Painter 由两种方法组成,绘画方法和他们应该重新绘画的方法。

class ExampleCustomPainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
  }

  
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
  }
}

Paintmethod 获取画布以及它内部的父部件的大小你现在可以用来绘制画布的是图形表示用它你可以直接执行命令比如画圆圈画直线画路径。

class ExampleCustomPainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.teal
      ..strokeWidth = 5
      ..strokeCap = StrokeCap.round;

    Offset startingPoint = Offset(0, size.height / 2);
    Offset endingPoint = Offset(size.width, size.height / 2);

    canvas.drawLine(startingPoint, endingPoint, paint);
  }

  
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

路径

如果你从 0 点开始,你在画布的左上角,从那里你可以开始画任何你想画的地方,这就是现在的方法画图。

我们稍后将讨论 should 重新绘制,因为我们将要绘制一些东西,但是现在让我们快速看一下 should 重新绘制方法。ShouldRepaint 方法是每次重新启动类时调用的方法。因此,每当您滚动窗口 widget 或窗口 widget 树并释放该类,然后返回到该类时,它都会检查我是否应该重新绘制该窗口 widget ,从而使您能够控制是否要一直重新绘制该窗口 widget 。

它可能发生随机的事情,或者当我告诉你的时候你渲染它,甚至永远不再渲染它,所以如果它一旦被绘制和重用,你可以大大提高性能。

好了,再回到画布的方法,我们现在要在画布上画。

canvas.drawPoints(PointMode.points, points, paint1);

例如,我们有两个类第一个是路径,我们必须初始化在路径中,我们给出了关于如何画线的信息。

final shapeBounds = Rect.fromLTWH(0, 1, size.width, size.height - avatarRadius);

final backgroundPath = Path()
    ..moveTo(shapeBounds.left, shapeBounds.top)
    ..lineTo(shapeBounds.bottomLeft.dx, shapeBounds.bottomLeft.dy)
    ..arcTo(avatarBounds, -3.14, 3.14, false)
    ..lineTo(shapeBounds.bottomRight.dx, shapeBounds.bottomRight.dy)
    ..lineTo(shapeBounds.topRight.dx, shapeBounds.topRight.dy)
    ..close();

从 a 点到 b 点,然后画一条弧线,然后从 c 点到 d 点,这是路径信息,我们要在这里画线。

   Paint line = Paint()
      ..color = borderColor
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke
      ..strokeWidth = width;

我们在另一边有 Paint 类 Paint 类提供了关于颜色样式和大小的信息例如你想画的笔画如果我们说画布点绘制路径那么我们必须先传入路径然后再绘制这条线你可以看到在应用程序中这些线显示正确那么有可能绘制文本实际上是有意义的。


void paint(Canvas canvas, Size size) {
  final textStyle = TextStyle(
    color: Colors.black,
    fontSize: 30,
  );
  final textSpan = TextSpan(
    text: 'Hello, Flutter.',
    style: textStyle,
  );
  final textPainter = TextPainter(
    text: textSpan,
    textDirection: TextDirection.ltr,
  );
  textPainter.layout(
    minWidth: 0,
    maxWidth: size.width,
  );
  final xCenter = (size.width - textPainter.width) / 2;
  final yCenter = (size.height - textPainter.height) / 2;
  final offset = Offset(xCenter, yCenter);
  textPainter.paint(canvas, offset);
}

有一个文本 Painter 类你可以直接在上面画文本所以如果你不想写每一行你可以为你的文本画每一行你可以使用文本 Painter 它已经为你做了同样的事情并且有一些预定义的类。

所以我已经提到了弧线什么是弧线艺术就是一个你想画的圆所以弧线是一个半圆你可以画,如果你有两个点像,

点 a 和点 b 之间的弧线是半圆你可以传递一些信息比如半径和深度之类的信息来画这个弧线非常容易用这些信息就可以画出你的弧线。

class ArcPainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    var paint1 = Paint()
      ..color = Colors.black
      ..style = PaintingStyle.stroke
      ..strokeWidth = 5;
    //draw arc
    canvas.drawArc(Offset(100, 100) & Size(100, 100),
        0, //radians
        2, //radians
        false,
        paint1);
  }

  
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

你可以从那里画另一个东西,你可以做的是贝塞尔曲线如果你从来没有听说过它我发现它实际上非常有趣,因为我通常使用它在 Photoshop 中每当你使用钢笔工具,你可以从一个点到另一个点,如果你继续点击钢笔工具,并拖动它离开,然后你可以看到曲线出现,这是贝塞尔曲线,所以它出现一个新的点,你的 a 和 b 的第三个点,你得到一个公平的点,它提供了如何让曲线发生的信息,你可以向前移动。

结束语

如果本文对你有帮助,请转发让更多的朋友阅读。

也许这个操作只要你 3 秒钟,对我来说是一个激励,感谢。

祝你有一个美好的一天~

猫哥课程


© 猫哥

  • 微信 ducafecat

  • https://wiki.ducafecat.tech

  • https://ducafecat.com

Last Updated:
Contributors: ducafecat