代码之家  ›  专栏  ›  技术社区  ›  Caiz22

颤振:使用相同的按钮启动和停止计时器

  •  0
  • Caiz22  · 技术社区  · 5 年前

    我有一个秒表,想要一个既能暂停又能启动的按钮。我正在与这一逻辑作斗争。当打印到控制台时,布尔值被设置为false,不允许我重新单击按钮。

    秒表投掷:

    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";
      }
    }
    

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

    0 回复  |  直到 5 年前
        1
  •  6
  •   flarkmarup    5 年前

    我通过添加 setState() 在开始和停止观察方法中,翻转所述方法中的逻辑,并添加 () => 在开始之前,在 onPressed 回调(这是交易破坏者)。 此外,我删除了 startStop = false; 从…起 updateTimer() .我简化了你的 startOrStop() 如果你的陈述不需要写 == 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";
      }
    }
    
    
        2
  •  1
  •   BrianDev    4 年前

    谢谢你的工作示例。这帮我解决了一个类似的问题。

    如果它对任何人都有帮助,我在flarkmarup的代码中添加了一些内容,这样图标就更符合流程。

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

    在FloatingActionButton(btn1)中,我用变量替换了图标,如: child: Icon(btnPlayStatus)),

    然后将SetState添加到startOrStop,如:

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