颤动 - 生命周期
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;
感谢阅读我的问题
我又想知道为什么当我导航到计时器页面时会打印如下所示的错误。
我想知道如何修复它。
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;