【发布时间】:2020-12-13 20:19:43
【问题描述】:
我正在开发一个项目,该项目有一个CustomPaint,它以绘制形状作为背景,当您点击屏幕时,它会在该特定位置绘制一个圆圈。我正在使用GestureDetector 获取点击数据并将其作为参数发送给_MyCustomPainter 类似于以下代码:
class MyApp extends StatefulWidget{
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Offset _circlePosition = Offset(-1, -1);
void setCirclePosition(Offset newPosition) {
setState(() {
this._circlePosition = newPosition;
});
}
void clearCircle() {
setState(() {
this._circlePosition = Offset(-1, -1);
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.green,
title: Text('My app'),
),
body: Container(
child: GestureDetector(
onTapDown: (detail) {
setCirclePosition(detail.localPosition);
},
onHorizontalDragStart: (detail) {
setCirclePosition(detail.localPosition);
},
onHorizontalDragUpdate: (detail) {
setCirclePosition(detail.localPosition);
},
onVerticalDragStart: (detail) {
setCirclePosition(detail.localPosition);
},
onVerticalDragUpdate: (detail) {
setCirclePosition(detail.localPosition);
},
onTapUp: (detail) {
clearCircle();
},
onVerticalDragEnd: (detail) {
clearCircle();
},
onHorizontalDragEnd: (detail) {
clearCircle();
},
child: LimitedBox(
maxHeight: 400,
maxWidth: 300,
child: CustomPaint(
size: Size.infinite,
painter: new _MyCustomPainter(
circlePosition: circlePosition,
),
),
),
),
),
),
);
}
}
class _MyCustomPainter extends CustomPainter {
_MyCustomPainter({
this.circlePosition,
});
final Offset circlePosition;
void _drawBackground(Canvas canvas) {
// draw the background
}
@override
void paint(Canvas canvas, Size size) {
_drawBackground(canvas);
if (circlePosition.dx != -1 && circlePosition.dy != -1) {
// draws a circle on the position
var circlePaint = Paint()..color = Colors.green;
canvas.drawCircle(circlePosition, 5, circlePaint);
}
}
@override
bool shouldRepaint(_MyCustomPainter old) {
return circlePosition.dx != old.circlePosition.dx ||
circlePosition.dy != old.circlePosition.dy;
}
}
所以这里的问题是,每次用户长按在屏幕上移动手指时,不变的背景都会被一遍又一遍地重新绘制,并且绘制这个特定的背景涉及很多代码.有shouldRepaint 方法,但它发出重新绘制整个小部件的信号。我怎样才能使背景只绘制一次,而不是在重绘时我只使用我之前创建的背景?使用PictureRecorder 生成图像,而不是在未来重绘时使用该图像是最好的方法吗?我的CustomPainter 是否应该扩展ChangeNotifier 以获得更好的性能?目前的方法可行,但我想知道如何改进它。
【问题讨论】:
-
扩展
ChangeNotifier(或在CustomPainter构造函数中使用repaint参数)用于通知您的画家重新绘制自己,现在您正在为每次更改创建一个全新的_MyCustomPainter
标签: flutter dart canvas flutter-layout