You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中点击按钮时通过CustomPainter触发自定义绘制

实现CustomPaint按需触发前景层绘制的解决方案

CustomPaint本身不支持直接从外部调用paint方法,你可以通过绑定可监听对象的方式实现按需触发重绘,不需要刷新整个组件,性能开销极低,具体实现步骤如下:

步骤1:自定义支持受控重绘的前景画笔类

继承CustomPainter时传入可监听对象作为repaint参数,同时新增控制覆盖层是否显示的标识:

import 'package:flutter/material.dart';

class OverlayForegroundPainter extends CustomPainter {
  // 控制覆盖层是否渲染的标识
  bool showOverlay = false;

  // 传入可监听对象用来触发主动重绘
  OverlayForegroundPainter(Listenable repaint) : super(repaint: repaint);

  @override
  void paint(Canvas canvas, Size size) {
    // 只有标识为true的时候才绘制前景覆盖层
    if (!showOverlay) return;

    // 这里替换为你自己的覆盖层绘制逻辑
    final overlayPaint = Paint()..color = Colors.black.withOpacity(0.6);
    canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), overlayPaint);
  }

  @override
  bool shouldRepaint(covariant OverlayForegroundPainter oldDelegate) {
    return oldDelegate.showOverlay != showOverlay;
  }
}

步骤2:在页面组件中声明相关实例

在State类中初始化可监听对象和画笔实例,生命周期结束时记得销毁资源:

class YourCustomPageState extends State<YourCustomPage> {
  // 用来触发画笔重绘的可监听对象
  final _paintTrigger = ChangeNotifier();
  // 前景画笔实例
  late final OverlayForegroundPainter _foregroundPainter;

  @override
  void initState() {
    super.initState();
    // 把可监听对象绑定到画笔
    _foregroundPainter = OverlayForegroundPainter(_paintTrigger);
  }

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

步骤3:给CustomPaint绑定前景画笔

直接把创建好的画笔实例传给CustomPaint的对应参数即可:

CustomPaint(
  size: const Size(300, 300), // 替换为你自己的尺寸
  painter: YourBackgroundPainter(), // 替换为你自己的背景画笔
  foregroundPainter: _foregroundPainter,
  child: // 你自定义的子组件
)

步骤4:点击按钮时主动触发重绘

修改覆盖层显示标识后调用可监听对象的通知方法,就会自动触发paint方法执行:

ElevatedButton(
  onPressed: () {
    // 切换覆盖层显示状态
    _foregroundPainter.showOverlay = !_foregroundPainter.showOverlay;
    // 主动触发画笔重绘,不需要调用setState
    _paintTrigger.notifyListeners();
  },
  child: const Text("切换前景覆盖层")
)

原理说明:CustomPainter的repaint参数接收的Listenable对象发送通知时,框架会自动调用对应画笔的paint方法执行绘制,只会重绘当前CustomPaint的对应层,不会触发整个组件树的刷新。

内容的提问来源于stack exchange,提问作者Ensei Tankado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 04:27:04