我正在尝试侦听变量更改以执行一些代码。因此,该变量是名为reset
的布尔值。一旦动画结束或按下了按钮(来自另一个窗口小部件),我想执行一些操作(例如重置动画控制器)。动画结束时执行某些操作,因为动画AnimationStatus.dismissed
结束后将成为其状态,并且将调用侦听器。然后,这使我可以使用回调函数onCountdownexpire
来相应地设置变量reset
,并根据设置的内容在if(widget.reset)
块中执行一些代码。因此,无需侦听这种情况。
问题:
但是,可以说(在另一个小部件中)按下了一个按钮,我将变量reset
设置为true。我希望动画停止并重置。我现在不能依靠AnimationStatus
侦听器,因为它仅在状态更改时执行 。我希望它在其状态期间重置。因此,我必须以某种方式收听变量widget.reset
。
我对此进行了一些研究,发现ValueNotifier
可能是一种解决方法,但是关于如何使用它的例子并不多。像我该如何去听呢?
代码:
class Countdown extends StatefulWidget {
final VoidCallback onCountdownExpire;
bool reset;
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.dismissed) {
debugPrint("Animation.dismissed");
widget.onCountdownExpire();
if (widget.reset) {
widget.reset = false;
controller.reverse(from: 1.0);
}
}
});
controller.reverse(from: 1.0);
}
... // omitted code
}
我尝试过的方法,但是似乎无法按预期进行:
class Countdown extends StatefulWidget {
final VoidCallback onCountdownExpire;
Countdown(this.onCountdownExpire);
ValueNotifier reset = ValueNotifier(false);
@override
CountdownState createState() => CountdownState();
}
class CountdownState extends State<Countdown> with TickerProviderStateMixin {
AnimationController controller;
@override
void initState() {
widget.reset.addListener(() {
debugPrint("value notifier is true");
controller.reverse(from: 1.0);
});
super.initState();
controller = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
)..addStatusListener((AnimationStatus status){
if (status == AnimationStatus.dismissed) {
debugPrint("Animation.dismissed");
widget.onCountdownExpire();
}
});
controller.reverse(from: 1.0);
}
... // omitted code
}
更新:解决方案(上面的)实际上是有效的,我只需要使用类似的方法来通知侦听器:
countdown.reset.notifyListeners();
// OR
countdown.reset.value = true;
答案 0 :(得分:6)
OP已在评论中得到答案。我只是在这里输入,因此问题已正确标记为已回答。
只需通知侦听器:
countdown.reset.notifyListeners();
// OR
countdown.reset.value = true;
贷方@pskink