【问题标题】:Flutter: Start and Stop Timer Using Same ButtonFlutter:使用相同的按钮启动和停止计时器
【发布时间】:2019-12-17 19:40:51
【问题描述】:

我有一个秒表,想要一个按钮来暂停和启动它。我正在努力解决这个问题。打印到控制台时,布尔值卡在 false 上,不会让我重新单击按钮。

stopwatch.dart:

class NewStopWatch extends StatefulWidget {

  @override
  _NewStopWatchState createState() => new _NewStopWatchState();
}

class _NewStopWatchState extends State<NewStopWatch> {

  Stopwatch watch = new Stopwatch();
  Timer timer;
  bool startStop = true;

  String elapsedTime = '';

  updateTime(Timer timer) {
    if (watch.isRunning) {
      setState(() {
        startStop = false;
        print("startstop Inside=$startStop");
        elapsedTime = transformMilliSeconds(watch.elapsedMilliseconds);
      });
    }
  }
@override
  Widget build(BuildContext context) {

    return new Container(
            padding: EdgeInsets.all(20.0),
            child: new Column(
              children: <Widget>[
                new Text(elapsedTime, style: new TextStyle(fontSize: 25.0)),
                SizedBox(height: 20.0),
                new Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    new FloatingActionButton(
                      heroTag: "btn1",
                        backgroundColor: Colors.red,
                        onPressed: startOrStop(),
                        child: new Icon(Icons.pause)),
                    SizedBox(width: 20.0),
                    new FloatingActionButton(
                      heroTag: "btn2",
                        backgroundColor: Colors.green,
                        onPressed: resetWatch,
                        child: new Icon(Icons.check)),
                  ],
                )
              ],
            ));
  }

  startOrStop() {
    print("startstop=$startStop");
    if(startStop == true) {
      startWatch();
    } else {
      stopWatch();
    }
  }

  startWatch() {
    startStop = true;
    watch.start();
    timer = new Timer.periodic(new Duration(milliseconds: 100), updateTime);
  }

  stopWatch() {
    startStop = false;
    watch.stop();
    setTime();
    startStop = true;
  }

  setTime() {
    var timeSoFar = watch.elapsedMilliseconds;
    setState(() {
      elapsedTime = transformMilliSeconds(timeSoFar);
    });
  }

  transformMilliSeconds(int milliseconds) {
    int hundreds = (milliseconds / 10).truncate();
    int seconds = (hundreds / 100).truncate();
    int minutes = (seconds / 60).truncate();
    int hours = (minutes / 60).truncate();

    String hoursStr = (hours % 60).toString().padLeft(2, '0');
    String minutesStr = (minutes % 60).toString().padLeft(2, '0');
    String secondsStr = (seconds % 60).toString().padLeft(2, '0');

    return "$hoursStr:$minutesStr:$secondsStr";
  }
}

当第一次单击第一个按钮时,秒表应该开始运行。当它被第二次点击时,它应该暂停它。

【问题讨论】:

  • 还没有回答您的解决方案,而是一些简单的问题:您为什么将布尔值命名为 startStop?知道true 的值会导致什么结果是不必要的复杂。它应该启动还是停止计时器?还有,为什么要在stopWatch()中多次设置startStop
  • 我最初将它设置为true,打算第一次单击按钮调用startWatch()方法。 stopWatch() 中的不同值用于实验目的

标签: asynchronous flutter dart timer widget


【解决方案1】:

感谢您的工作示例。这帮助我解决了类似的问题。

如果它对任何人有帮助,我在 flarkmarup 的代码中添加了一些位,以便图标与流程更相关。

在顶部我添加了一个变量: IconData btnPlayStatus = Icons.play_arrow;

在 FloatingActionButton (btn1) 中,我将 Icon 替换为如下变量: child: Icon(btnPlayStatus)),

然后将 SetState 添加到 startOrStop 中,如:

  startOrStop() {
    if(startStop) {
      setState(() {
        btnPlayStatus = Icons.pause;
      });
      startWatch();
    } else {
      setState(() {
        btnPlayStatus = Icons.play_arrow;
      });
      stopWatch();
    }
  }

【讨论】:

    【解决方案2】:

    我通过在您的开始和停止手表方法中添加setState() 解决了您的代码,翻转了上述方法中的逻辑,并在onPressed 回调中的 startOrStop 之前添加了() =&gt;(这是交易破坏者)。 此外,我从updateTimer() 中删除了startStop = false;。我简化了您的startOrStop() if 语句,因为您在检查布尔值时不需要写== true,您可以在评估布尔值时简单地写if(startStop)

    工作示例:

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    
    class NewStopWatch extends StatefulWidget {
    
      @override
      _NewStopWatchState createState() => _NewStopWatchState();
    }
    
    class _NewStopWatchState extends State<NewStopWatch> {
    
      Stopwatch watch = Stopwatch();
      Timer timer;
      bool startStop = true;
    
      String elapsedTime = '';
    
      updateTime(Timer timer) {
        if (watch.isRunning) {
          setState(() {
            print("startstop Inside=$startStop");
            elapsedTime = transformMilliSeconds(watch.elapsedMilliseconds);
          });
        }
      }
      @override
      Widget build(BuildContext context) {
    
        return Container(
          padding: EdgeInsets.all(20.0),
          child: Column(
            children: <Widget>[
              Text(elapsedTime, style: TextStyle(fontSize: 25.0)),
              SizedBox(height: 20.0),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  FloatingActionButton(
                      heroTag: "btn1",
                      backgroundColor: Colors.red,
                      onPressed: () => startOrStop(),
                      child: Icon(Icons.pause)),
                  SizedBox(width: 20.0),
                  FloatingActionButton(
                      heroTag: "btn2",
                      backgroundColor: Colors.green,
                      onPressed: null, //resetWatch,
                      child: Icon(Icons.check)),
                ],
              )
            ],
          ),
        );
      }
    
      startOrStop() {
        if(startStop) {
          startWatch();
        } else {
          stopWatch();
        }
      }
    
      startWatch() {
        setState(() {
          startStop = false;
          watch.start();
          timer = Timer.periodic(Duration(milliseconds: 100), updateTime);
        });
      }
    
      stopWatch() {
        setState(() {
          startStop = true;
          watch.stop();
          setTime();
        });
      }
    
      setTime() {
        var timeSoFar = watch.elapsedMilliseconds;
        setState(() {
          elapsedTime = transformMilliSeconds(timeSoFar);
        });
      }
    
      transformMilliSeconds(int milliseconds) {
        int hundreds = (milliseconds / 10).truncate();
        int seconds = (hundreds / 100).truncate();
        int minutes = (seconds / 60).truncate();
        int hours = (minutes / 60).truncate();
    
        String hoursStr = (hours % 60).toString().padLeft(2, '0');
        String minutesStr = (minutes % 60).toString().padLeft(2, '0');
        String secondsStr = (seconds % 60).toString().padLeft(2, '0');
    
        return "$hoursStr:$minutesStr:$secondsStr";
      }
    }
    
    

    【讨论】:

    • 谢谢!这正是我所追求的! onPressed: () =&gt; startOrStop()onPressed: startStop 有什么区别——他们不是都调用方法吗?
    • 您应该写onPressed: () { your code here},但fat arrow 是该方法的简写语法。 Link 到一篇强调该问题的文章。
    • 另一个explanation的语法
    猜你喜欢
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多