当计时器在特定小部件中结束时,我试图执行回调函数,但我不断收到此异常:
I / flutter(16413):引发了另一个异常:在构建过程中调用了setState()或markNeedsBuild()。
所以我有一个名为countdown
的小部件:
class Countdown extends StatefulWidget {
final VoidCallback onCountdownExpire;
Countdown(this.onCountdownExpire);
@override
CountdownState createState() => CountdownState();
}
class CountdownState extends State<Countdown> with TickerProviderStateMixin {
AnimationController controller;
String get timerString {
Duration duration = controller.duration * controller.value;
return '${duration.inMinutes}:${(duration.inSeconds % 60).toString()}';
}
@override
void initState() {
super.initState();
controller = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
)..addStatusListener((AnimationStatus status){
if (status == AnimationStatus.completed)
widget.onCountdownExpire();
});
controller.reverse(from: 1.0);
}
...
...
... // omitted code
}
因此,一旦动画完成,它将调用回调函数:
class _QuizPageState extends State<QuizPage> {
... // omitted code
@override
void initState() {
... // omitted code
}
void onCountdownExpire() {
setState(() {
_topContentImage = AssetImage(questions[questionNum++].imagePath);
});
}
... // omitted code
}
我尝试遵循solution,但是它不起作用,并且给了我同样的例外:
void onCountdownExpire() =>
setState(() {
_topContentImage = AssetImage(questions[questionNum++].imagePath);
});
我也尝试过此方法,但无济于事:
@override
void initState() {
super.initState();
controller = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
)..addStatusListener((AnimationStatus status) =>
(status == AnimationStatus.completed) ?
widget.onCountdownExpire():null
);
controller.reverse(from: 1.0);
}
答案 0 :(得分:0)
也许尝试包含'dart:async':
import 'dart:async';
然后尝试将对onCountdownExpire
函数的调用包装在短暂的Timer()
中:
...
Timer(
Duration(milliseconds:50),
() {
if (status == AnimationStatus.completed)
widget.onCountdownExpire();
},
);
...
这将使setState()
发生在动画最后一帧的构建阶段之外。
最有可能发生此错误,因为Countdown()
小部件的重绘过程中正在重绘QuizPage()
。添加Timer()
将迫使更新以异步方式在build()
范围之外进行,并且仍将获得相同的结果而不会出错。