Flutter番茄钟应用Timer未初始化空安全报错如何解决?
报错原因
- 你当前使用的Flutter版本已启用空安全校验,非空类型的变量必须在声明时初始化,或通过关键字保证使用前完成赋值。
- 你使用
late Timer _timer声明时,late关键字仅向编译器承诺你会在使用前完成变量赋值,但实际业务逻辑中,用户可在未点击Start按钮(未执行_timer赋值逻辑)时直接点击Stop按钮,触发未初始化的运行时报错。
解决方案
你当前场景下_timer天然是允许为null的(页面初始加载时无运行中的计时器),直接将其声明为可空类型即可,修改步骤如下:
- 将_timer的声明代码修改为:
Timer? _timer;
- 所有调用_timer的位置改为空安全调用,避免空指针:
原_timer.cancel()改为_timer?.cancel()
原if (_timer != null)判断可以保留,也可以直接省略(空安全调用符会自动处理空判断)
修改后可正常运行的完整代码
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _seconds = 00; int _minutes = 25; // 修改为可空类型 Timer? _timer; var f = NumberFormat("00"); void _stopTimer(){ // 空安全调用,自动处理空判断 _timer?.cancel(); setState(() { _seconds = 0; _minutes = 25; }); } void _startTimer(){ _timer?.cancel(); if (_minutes > 0){ _seconds = _minutes * 60; } if (_seconds >60){ _minutes = (_seconds/60).floor(); _seconds -= (_minutes * 60); } _timer = Timer.periodic(Duration(seconds: 1), (timer) { setState(() { if (_seconds > 0){ _seconds--; } else { if (_minutes >0){ _seconds = 59; _minutes--; } else { _timer?.cancel(); print("Timer Complete"); } } }); }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "${f.format(_minutes)} : ${f.format(_seconds)}", style: TextStyle( color: Colors.white, fontSize: 48, ), ), ], ), SizedBox( height: 300, ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ ElevatedButton( onPressed: _stopTimer, style: ElevatedButton.styleFrom( backgroundColor: Colors.black, shape: CircleBorder( side: BorderSide(color: Colors.orange[300]!) ), padding: const EdgeInsets.all(40.0) ), child: const Text( "Stop", style: TextStyle( color: Colors.white, fontSize: 24, ), ), ), ElevatedButton( onPressed: _startTimer, style: ElevatedButton.styleFrom( backgroundColor: Colors.orange[300], shape: CircleBorder( side: BorderSide(color: Colors.orange[300]!) ), padding: const EdgeInsets.all(40.0) ), child: const Text( "Start", style: TextStyle( color: Colors.white, fontSize: 24, ), ), ), ], ), ], ), ); } }
注:代码中已同步将废弃的
RaisedButton替换为新版推荐的ElevatedButton,如果你使用的Flutter版本较低,可保留原来的按钮代码,仅修改_timer相关逻辑即可正常运行。
内容的提问来源于stack exchange,提问作者iocomxda
相关产品推荐
相关产品推荐

