Flutter CustomPaint 自定义绘制指南:原理、参数与动画实战

清欢
清欢
发布时间:2026-10-15| 6人浏览过
原创

深入了解 Flutter 中的 CustomPaint 组件,掌握 Canvas 绘图机制。本文解析 painter、size 等关键参数,并通过重写 CustomPainter 与 AnimationController 结合,演示如何实现从静态绘制到动态动画的完整流程。

CustomPaint 核心机制与参数

CustomPaint 是 Flutter 中用于执行自定义绘制的组件,它提供了一个 canvas,允许开发者在专门的绘制阶段进行内容渲染。其默认绘制顺序为:先执行 painter,再绘制 child 控件,最后执行 foregroundPainter。因此,background 层(painter)位于子组件下方,而 foregroundPainter 则覆盖在子组件之上。

在使用 CustomPaint 时,必须注意绘制边界。所有绘画指令应在原点开始并包含给定大小的矩形区域内进行;超出该边界的内存可能不足以光栅化命令,导致未定义行为,必要时可配合 ClipRect 使用。

关键构造函数参数解析

CustomPaint 的构造函数包含多个影响性能和布局的参数:

  • painter: 核心参数,负责背景绘制,需继承自 CustomPainter。
  • foregroundPainter: 可选参数,用于在 child 之上进行叠加绘制。
  • size: 指定 canvas 的大小。受 Constrains 约束,仅在 Loose 模式下有效。若为 Tight 模式或约束不足,size 将取最小值。
  • isComplex: 性能优化标识。设为 false 时由合成器决定缓存;设为 true 时提示系统缓存该层绘画结果,以减少重复绘制开销。
  • willChange: 仅当 isComplex 为 true 时生效,告知系统下一帧绘画内容可能会发生变化,防止过度缓存导致画面滞后。

实现静态绘制

要实现自定义形状,需创建一个继承自 CustomPainter 的类,并重写两个方法:绘制逻辑所在的 paint 方法和决定是否重绘的 shouldRepaint。

  1. 定义 Painter 类:初始化 Paint 对象(如颜色、描边宽度),并在 paint 方法中调用 canvas 指令。
  2. 配置 shouldRepaint:若绘制内容完全不受外界状态影响,直接返回 false 即可提升性能。
class MyPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // 配置画笔样式
    var paint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.0;

    // 绘制一条水平线段
    canvas.drawLine(
        Offset(0, 10),
        Offset(100, 10),
        paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

将实例化的 Painter 赋值给 CustomPaint 的 painter 参数即可完成绑定:

CustomPaint(painter: MyPainter());

处理 size 限制问题

如果 CustomPaint 包裹在无约束环境中,其内部获取的 size 可能为 Size.zero。解决此问题有两种常见方式:

1. **外层添加 SizedBox**:强制设置宽高约束。

SizedBox(
    height: 20,
    width: 20,
    child: CustomPaint(painter: MyPainter()),
)

2. **直接指定 size 参数**:在 Loose 约束下,指定的 size 可作为建议尺寸传递给 painter(但最终以实际可用空间为准)。

SizedBox(
    height: 20,
    width: 20,
    child: CustomPaint(
      size: Size(30, 30),
      painter: MyPainter(),
    ),
)

结合动画实现动态效果

CustomPainter 提供了 repaint 参数(类型为 Listenable?),用于触发视图刷新以支持动画。通过与 AnimationController 配合,可以实现流畅的动态绘制。

以下示例展示了一条红色线条随时间逐渐变长的效果:

class MyAnimatedPainter extends CustomPainter {
  final Animation _animation;

  MyAnimatedPainter(this._animation) : super(repaint: _animation);

  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.0;

    // 利用动画值动态改变终点坐标
    canvas.drawLine(
        Offset(0, 10),
        Offset(100 * _animation.value, 10),
        paint);
  }

  @override
  bool shouldRepaint(covariant MyAnimatedPainter oldDelegate) {
    return false; // 由 repaint 控制自动刷新,无需手动判断
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({super.key});

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget>
    with SingleTickerProviderStateMixin {
  late AnimationController controller;

  @override
  void initState() {
    super.initState();
    // 创建持续2秒的循环动画
    controller = AnimationController(
      duration: Duration(seconds: 2),
      vsync: this,
    )..repeat();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 40,
      width: 150,
      child: CustomPaint(
        // 传入 animation.view 作为 repaint 监听源
        painter: MyAnimatedPainter(controller.view),
      ),
    );
  }
}

运行上述代码后,屏幕上会出现一条从短到长、不断循环变化的红色直线。这就是通过 CustomPaint 和 AnimationController 结合实现的基础动画案例。

以上就是Flutter CustomPaint绘制widget使用示例的详细内容,更多关于Flutter CustomPaint绘制widget的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。