在抖动几秒钟后向绘图添加一条线



我们想要在之前使用customPaint的paint函数绘制的绘图中添加一条线。将显示如下图:

输入图片描述

我们想在几秒钟后将图纸更改为以下图纸:

输入图片描述

意思是在原图纸上加一条短线。用户将选择他在绘图更改之前看到的绘图。我们尝试用颤振定时器和颤振未来来解决这个问题。延迟,但在我们设置的时间之后什么也没有发生,调试控制台显示:"未处理异常:对象已被处置"。我们很乐意知道是否有其他选项可以帮助我们达到我们的目标:不同的定时功能,另一个与计时器或未来延迟一起工作的绘图选项我们试着用这个函数来解决问题:

void paint(Canvas canvas, Size size){
const p1 = Offset(50, 50);
const p2 = Offset(50, 300);
const p3 = Offset(50, 50);
const p4 = Offset(250, 50);
const p5 = Offset(250, 50);
const p6 = Offset(250, 150);
const p7 = Offset(250, 150);
const p8 = Offset(250, 300);
final paint = Paint()
..color = Colors.black
..strokeWidth = 4
..strokeCap = StrokeCap.round;
canvas.drawLine(p1, p2, paint);
canvas.drawLine(p3, p4, paint);
canvas.drawLine(p5, p6, paint);
Timer(
Duration(seconds: 1),
() {
canvas.drawLine(p7, p8, paint);
},
);'

这个部分位于

下面的函数的下一行。

自定义painter实现的方式不允许对画布对象进行任何异步调用,因为它被销毁,并且paint函数提供了一个新的画布对象,因此错误信息是旧的画布对象被销毁。

您可以通过在堆栈中使用两个自定义画家并向第二个添加延迟来轻松实现此延迟绘画。

class DelayedDraw extends StatefulWidget {
final Size size;
const DelayedDraw({ super.key, required this.size });
@override
State< DelayedDraw > createState() => _ DelayedDraw State();
}
class _ DelayedDraw State extends State<DelayedDraw > {
bool drawSecond = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback((_) => 
Future.delayed(const Duration(seconds: 1))
.then((_) => setState(() => showSecond = true))
);
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
CustomPaint(
painter: BaseShapePainter(),
size: widget.size,
),
if(drawSecond) 
CustomPaint(
painter: SecondShapePainter(),
size: widget.size,
),
],
);
}
}

为此,需要使用bool shouldRepaint(oldDelegate)函数。当你返回true时,这个方法会重新渲染你的绘图。

所以对我来说最好的方法是这样做:


class MyCustomPainter extends CustomPainter {
const MyCustomPainter({Key? key, required this.addLine});
final bool addLine;
@override
void paint(Canvas canvas, Size size) {
const p1 = Offset(50, 50);
const p2 = Offset(50, 300);
const p3 = Offset(50, 50);
const p4 = Offset(250, 50);
const p5 = Offset(250, 50);
const p6 = Offset(250, 150);
const p7 = Offset(250, 150);
const p8 = Offset(250, 300);
final paint = Paint()
..color = Colors.black
..strokeWidth = 4
..strokeCap = StrokeCap.round;
canvas.drawLine(p1, p2, paint);
canvas.drawLine(p3, p4, paint);
canvas.drawLine(p5, p6, paint);
if (addLine) {
canvas.drawLine(p7, p8, paint);
}
}
@override
bool shouldRepaint(MyCustomPainter oldDelegate) {
return oldDelegate.addLine != this.addLine;
}
}

在你的StatefulWidget中像这样:


bool addLine = false;
@override
void initState() {
super.initState();
Future.delayed(const Duration(seconds: 1), () {
setState(() {
addLine = true;
});
});
}
@override
Widget build(BuildContext context) {
...
CustomPaint(
painter: MyCustomPainter(addLine: addLine)
)
}

最新更新