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

如何在Flutter中用CustomPainter结合touchable包修改绘制对象颜色

解决方法

要实现点击眼睛切换颜色的效果,核心是让CustomPainter响应状态变化并触发重绘,具体实现步骤如下:

  • 给MapPainter添加可修改的颜色参数和点击回调,用来接收眼睛颜色、通知父组件处理点击事件
  • 在父组件中维护眼睛颜色的状态,通过setState()触发重绘
  • 优化shouldRepaint方法,只在颜色变化时重绘,提升性能

修改后的完整代码

1. 改造MapPainter类

class MapPainter extends CustomPainter {
  final BuildContext context;
  final Color eyeColor; // 控制眼睛颜色的参数
  final VoidCallback onEyeTap; // 点击眼睛的回调

  MapPainter(this.context, {required this.eyeColor, required this.onEyeTap});

  @override
  void paint(Canvas canvas, Size size) {
    var myCanvas = TouchyCanvas(context, canvas);
    // 基础画笔配置
    var paint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.0;

    // 绘制脸框
    myCanvas.drawCircle(
      Offset(size.width / 2, size.height / 2),
      size.width / 2,
      paint,
    );

    // 绘制眼睛(使用传入的eyeColor)
    var eyePaint = Paint()
      ..style = PaintingStyle.fill
      ..color = eyeColor; // 用外部参数控制颜色

    myCanvas.drawCircle(
      Offset(size.width * 0.25, size.height * 0.25),
      size.width * 0.1,
      eyePaint,
      onTapDown: (tapdetail) {
        onEyeTap(); // 触发父组件的状态更新回调
      },
    );
  }

  @override
  bool shouldRepaint(covariant MapPainter oldDelegate) {
    // 只有当颜色变化时才重绘,避免不必要的性能消耗
    return oldDelegate.eyeColor != eyeColor;
  }
}

2. 父StatefulWidget实现状态管理

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

  @override
  State<MapScreen> createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {
  // 初始眼睛颜色设为黑色
  Color _eyeColor = Colors.black;

  void _toggleEyeColor() {
    setState(() {
      // 点击后切换颜色,示例:黑变红、红变黑
      _eyeColor = _eyeColor == Colors.black ? Colors.red : Colors.black;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: SizedBox(
          width: 300,
          height: 300,
          child: TouchableCanvas(
            child: CustomPaint(
              painter: MapPainter(
                context,
                eyeColor: _eyeColor,
                onEyeTap: _toggleEyeColor, // 传递状态更新回调
              ),
            ),
          ),
        ),
      ),
    );
  }
}

关键说明

  • MapPainter不再是无状态组件,通过外部传入的eyeColor控制绘制颜色,点击事件通过onEyeTap回调通知父组件
  • 父组件通过setState()更新_eyeColor,触发CustomPaint重新创建MapPainter实例,shouldRepaint方法确保仅在颜色变化时重绘
  • 眼睛画笔使用PaintingStyle.fill让颜色变化更直观,你可以根据需求改回stroke模式

内容的提问来源于stack exchange,提问作者Landon Pattison

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:05:20