【问题标题】:Flutter start and stop stopwatch from parent widgetFlutter 从父小部件开始和停止秒表
【发布时间】:2020-12-09 00:25:57
【问题描述】:

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

我的秒表代码

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 类中停止秒表只是为了交叉检查,但效果很好。

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

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

【问题讨论】:

    标签: flutter dart timer stopwatch


    【解决方案1】:

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

    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();
        }
      }
    

    不建议在父Widget中调用Widget函数,因为每次构建都会有一个新的Widget实例

    【讨论】:

    • 感谢您的回复。我试过这个,但它不工作。我想我做错了什么。共享飞镖垫网址。 dartpad.dev/70a97f62f6bf2d3c51e322c651566240
    • 但是当我在 StopWatch 中启动和停止时,它工作正常。只是我无法从父级触发开始和停止。如果您尝试从父级启动计时器,它不会启动。
    • 我没有使用计时器,我在这里使用秒表
    • 我已经按照建议进行了更改,即使它不起作用。你能看看飞镖网址,看看我做错了什么。
    猜你喜欢
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    相关资源
    最近更新 更多