24.Flutter:使用CustomPaint构建酷炫的Widget

目录传送门:《Flutter快速上手指南》先导篇

到目前为止,Flutter 已经提供了 30 多种不同的 Widget 用于组合构建视图。

但对于一些复杂的视图,用 SDK 提供的这些 Widget 仍然无法组合出来 ? 。

我们必须自己绘制这些视图,就像在 Android 中使用 Canvas 和 Paint 来进行绘制那样 ? 。

在 Flutter 中,当然也有可以让你自由绘制的方案,他就是 CustomPaint

CustomPaint

CustomPaint 也是一个 Widget。

你可把它嵌到视图树的任意一个节点位置。

先看看它的常用属性:

属性 类型 说明
painter CustomPainter 背景画笔,绘制内容会显示在child子节点后面
foregroundPainter CustomPainter 前景画笔,绘制内容会显示在child子节点前面
size Size 设置绘制区域的大小。如果有child,则忽略该参数,且绘制区域为child的尺寸
isComplex bool 是否复杂的绘制,如果是,Flutter会应用一些缓存策略来减少重复渲染的开销。默认false
willChange bool 和isComplex配合使用,当启用缓存时,该属性代表在下一帧中绘制是否会改变。默认false
child Widget 没错,CustomPaint是可以包含一个子节点的

从 CustomPaint 的属性可以看出,实际绘制是通过 CustomPainter 来完成的。

以 child 为基准,CustomPainter 分为两个部分,一个是绘制在 child 上面的 pinter,一个是绘制在 child 下面的 foregroundPainter

? 看个例子:

CustomPaint(
    isComplex: true,
    willChange: true,
    size: Size(deviceSize.width, deviceSize.height),
    painter: GamePainter(background, maliao, position),
    foregroundPainter: ForegroundGamePainter(),
  )
复制代码

马良神笔 CustomPainter

CustomPainter 是一个抽象类,你需要继承它实现自己的逻辑。

class MyPainter extends CustomPainter {

  @override
  paint(Canvas canvas, Size size)  {
    ...
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
复制代码

继承 CustomPainter 最重要的是实现 paint(Canvas canvas, Size size)shouldRepaint(CustomPainter oldDelegate) 这两个函数。

  • paint() 中是绘制逻辑,可以在这获得画布 Canvas 和 画布的大小 Size

  • shouldRepaint() 返回 true 才会进行重绘,否则就只会绘制一次。你可以通过一些条件判断来决定是否每次绘制,这样能够节约系统资源。

实现 CustomPainter 最重要的就是在 paint() 中写绘制逻辑。

? 一个例子:

class MyPainter extends CustomPainter {
  @override
  void paint(ui.Canvas canvas, ui.Size size) {
    Paint paint = Paint()
      ..isAntiAlias = true
      ..color = Colors.blueAccent
      ..strokeWidth = 10
      ..style = PaintingStyle.fill;

    canvas.drawLine(Offset(10, 10), Offset(250, 250), paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
复制代码

? 看看效果:

在绘制过程中,有两个重要的角色:PaintCanvas

Paint

Paint 是画笔,在 Canvas 上作画就是依靠它去 "执行" 的。

看看 Paint 有那些常用属性:

属性 类型 说明
isAntiAlias bool 是否开启抗锯齿,开启抗锯齿能够是边缘平滑,当然也更消耗系统资源
color Color 颜色
colorFilter ColorFilter 会对颜色进行变换
filterQuality FilterQuality 设置绘制的图像质量
invertColors bool 是否使用反向颜色。绘制图片时也能够反转图片的颜色
maskFilter MaskFilter 设置遮罩效果。比如高斯模糊
shader Shader 渐变颜色。会覆盖color
strokeCap StrokeCap 设置绘制形状的边缘风格。如圆角、方形等
strokeJoin StrokeJoin 设置两个绘制形状衔接处的风格。如圆角、方形等
strokeWidth double 画笔的宽度
style PaintingStyle 填充方式。PaintingStyle.fill-充满;PaintingStyle.stroke-空心
blendMode BlendMode 像素混合模式。当画一个shape或者合成图层的时候会生效。

以上就是 Paint 常用的属性,你可以都试试看看效果。

这是一段 Paint 的配置代码:

Paint paint = Paint()
  ..isAntiAlias = true
  ..color = Colors.redAccent
  ..strokeWidth = 10
  ..style = PaintingStyle.fill
  ..filterQuality = FilterQuality.high
  ..strokeCap = StrokeCap.round
  ..strokeJoin = StrokeJoin.round
  ..maskFilter = MaskFilter.blur(BlurStyle.normal, 50)
  ..invertColors = false
  ..blendMode = BlendMode.color
  ..shader = ui.Gradient.linear(
      Offset(0, 0), Offset(100, 100), [Colors.red, Colors.blueAccent])
复制代码

Canvas

Canvas 作为画布,它和在 Android 使用的 Canvas 在很多接口上很像。

它包含了很多基础的绘制操作,通过组合这些基础的绘制操作,可以绘制出几乎任何的视图。

Canvas 的操作主要有两类:

  • 针对 Canvas 的变换操作,如平移、旋转、缩放、图层等操作。

  • 绘制基础图形的操作,如线段、路径、图片、几何图形等。

Canvas 的这些操作后续再详细讲解 ?。

目录传送门:《Flutter快速上手指南》先导篇

如何找到我?

传送门:CoorChice 的主页

传送门:CoorChice 的 Github


转载于:https://juejin.im/post/5c94c4a3e51d450c1625db5a

你可能感兴趣的:(24.Flutter:使用CustomPaint构建酷炫的Widget)