从父小部件颤振启动和停止秒表

Flutter start and stop stopwatch from parent widget

我有一个有状态的秒表小部件,我在多个页面上使用该小部件。我正在加载时启动秒表,但我想在某些情况下从我的父小部件停止秒表,但这不起作用。

我的秒表代码

class StopWatch extends StatefulWidget {
  start() => createState().start();
  stop() => createState().stop();

  @override
  _StopWatchState createState() => _StopWatchState();
}

class _StopWatchState extends State<StopWatch> {

  String timeToDisplay = '00:00:00';
  Stopwatch swatch = Stopwatch();
  final duration = const Duration(seconds: 1);

  void startTimer() {
    Timer(duration, keepRunning);
  }

  void keepRunning() {
    if (swatch.isRunning) {
      startTimer();
    }

    setState(() {
      var hours = swatch.elapsed.inHours.toString().padLeft(2, "0");
      var minutes = (swatch.elapsed.inMinutes % 60).toString().padLeft(2, "0");
      var seconds = (swatch.elapsed.inSeconds % 60).toString().padLeft(2, "0");

      timeToDisplay = hours + ':' + minutes + ':' + seconds;
    });
  }

  void start() {
    swatch.start();
    startTimer();
  }

  void stop() {
    swatch.stop();
  }

  void pause() {

  }

  @override
  void initState() {
    // TODO: implement initState
    start();
    super.initState();
  }

  @override
  void setState(fn) {
    if(mounted){
      super.setState(fn);
    }
  }
  
  @override
  void dispose() {
    // TODO: implement dispose
    swatch.stop();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(
        timeToDisplay,
        style: TextStyle(
            fontSize: 50.0, fontWeight: FontWeight.bold),
      ),
    );
  }
}

父控件。

class RecordTrackScreen extends StatefulWidget {
  static String id = 'record-track';

  @override
  _RecordTrackScreenState createState() => _RecordTrackScreenState();
}

class _RecordTrackScreenState extends State<RecordTrackScreen> {
  stopTimer() {
    if (condition is true) {
      StopWatch().stop();
    }
  }
}

如果条件满足但秒表未停止,则 StopTimer 正在调用停止方法。 我试图在 StopWatch class 中停止秒表只是为了交叉检查但工作正常。

飞镖垫Url - https://dartpad.dev/70a97f62f6bf2d3c51e322c651566240

我不确定我做错了什么。请帮忙。

这行代码无法停止秒表,因为它正在停止秒表的新实例,这与您使用的秒表不同。

StopWatch().stop();

使用布尔值控制秒表的停止和启动

MyWidget 更改为有状态小部件

 bool isStop = false;

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      StopWatch(isStop: isStop),
      RaisedButton(
          onPressed: () {
            setState(() {
              isStop = true;
            });
          },
          child: Text('stop')),
      RaisedButton(
          onPressed: () {
            setState(() {
              isStop = false;
            });
          },
          child: Text('start'))
    ]);
  }

秒表:

class StopWatch extends StatefulWidget {
  final bool isStop;

  const StopWatch({Key key, this.isStop}) : super(key: key);

  @override
  _StopWatchState createState() => _StopWatchState();
}

class _StopWatchState extends State<StopWatch> {
  //...some code


  @override
  void didUpdateWidget(StopWatch oldWidget) {
    super.didUpdateWidget(oldWidget);
    // Check isStop value is different from the previous state
    // this function will trigger when every time this widget is build
    if (oldWidget.isStop != widget.isStop) {
      widget.isStop ? stop() : start();
    }
  }

Not suggest to call the Widget function in the parent Widget, since every time build, there will be a new instance of the Widget