聆听颤动中的可变变化

时间:2019-06-03 06:13:21

标签: flutter dart

我正在尝试侦听变量更改以执行一些代码。因此,该变量是名为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;  

1 个答案:

答案 0 :(得分:6)

OP已在评论中得到答案。我只是在这里输入,因此问题已正确标记为已回答。

只需通知侦听器:

countdown.reset.notifyListeners();
// OR
countdown.reset.value = true;

贷方@pskink