颤动 - 生命周期

Flutter - Life Cycle

感谢阅读我的问题

我又想知道为什么当我导航到计时器页面时会打印如下所示的错误。

我想知道如何修复它。

The following LateError was thrown while finalizing the widget tree: LateInitializationError: Field 'timer' has not been initialized.

这是我的计时器代码!

class Pomodoro extends StatefulWidget {
  @override
  _PomodoroState createState() => _PomodoroState();
}

class _PomodoroState extends State<Pomodoro> {
  double coinCount = 0;
  Stopwatch watch = Stopwatch();
  late Timer timer;
  bool startStop = true;

  String elapsedTime = '';

  @override
  void dispose() {
    timer.cancel();
    super.dispose();
  }

  updateTime(Timer timer) {
    if (watch.isRunning) {
      setState(() {
        elapsedTime = transformMilliSeconds(watch.elapsedMilliseconds);
      });
      if (coinCount == 360000) {
        context.read<Counts>().add(1);
        coinCount = 0;
      } else {
        coinCount = coinCount + 10;
      }
      context.read<Times>().timeAdd(100);
    }
  }

  restartTimer() {
    updateTime(timer).cancel();
    setState(() {
      startStop = true;
      watch.stop();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        elevation: 0,
        backgroundColor: Colors.white,
        leading: IconButton(
          icon: Icon(Icons.arrow_back, color: Colors.black),
          onPressed: () => Navigator.of(context).pop(),
        ),
      ),
      body: Container(
        padding: EdgeInsets.all(20.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(elapsedTime,
                style: TextStyle(fontFamily: 'Kitto', fontSize: 25.0)),
            SizedBox(height: 20.0),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                IconButton(
                  splashColor: Colors.transparent,
                  highlightColor: Colors.transparent,
                  onPressed: () => startOrStop(),
                  icon: Image.asset('assets/button.png'),
                  iconSize: 50,
                )
              ],
            )
          ],
        ),
      ),
    );
  }

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

如果您知道如何修复它,希望您能回答我的问题。

非常感谢您的回答。

祝你有愉快的一天!

我认为在那种情况下你不应该使用 late。 add late to field 表示该字段会在你第一次使用的时候进行初始化。 当您坚信第一次使用 late 字段时它将被初始化,请使用 late 。永远记住,使用 late 会使你的代码不那么安全,并增加运行时错误的可能性。

您不需要延迟变量,您需要一个可为空的变量。如果您需要检查是否初始化了某些东西,您应该使用可空变量,并且您的代码已经设置为检查空值。

改变一下

late Timer timer;

Timer? timer;