如何在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
相关产品推荐
相关产品推荐

