Flutter空安全下如何在类中声明字段并在initState中初始化
Flutter空安全下State类字段延迟初始化解决方案
你遇到的问题是Dart空安全机制对非空变量初始化时机的校验规则导致的,可通过以下两种方案解决:
方案1:使用late关键字(推荐)
Dart的late关键字用于标记会在首次使用前完成初始化的非空变量,刚好匹配State中initState初始化、后续生命周期才使用的场景,修改方式非常简单:
class _TabBarInsideAppBarDemoState extends State<TabBarInsideAppBarDemo> { // 加late关键字即可,告诉编译器你会在使用前完成初始化 late TabController tabController; @override void initState() { super.initState(); tabController = TabController(length: 3, vsync: this); } @override void dispose() { // 可以正常调用,late标记的变量属于非空类型 tabController.dispose(); super.dispose(); } // 其余代码无需修改 Widget getTabBar() { return TabBar(controller: tabController, tabs: [ Tab(text: "Add", icon: Icon(Icons.add)), Tab(text: "Edit", icon: Icon(Icons.edit)), Tab(text: "Delete", icon: Icon(Icons.delete)), ]); } Widget getTabBarPages() { return TabBarView(controller: tabController, children: <Widget>[ Container(color: Colors.red), Container(color: Colors.green), Container(color: Colors.blue) ]); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( flexibleSpace: SafeArea( child: getTabBar(), ), ), body: getTabBarPages()); } }
注意:该方案下必须保证
initState中确实完成了变量赋值,否则运行时会抛出LateInitializationError异常,你当前的场景完全符合要求,不会有问题。
方案2:可空类型+空安全调用
如果你坚持使用可空类型声明,只需要在调用dispose时使用空安全调用符?即可,空值时不会执行方法,不会抛出异常:
class _TabBarInsideAppBarDemoState extends State<TabBarInsideAppBarDemo> { TabController? tabController; @override void initState() { super.initState(); tabController = TabController(length: 3, vsync: this); } @override void dispose() { // 加?空安全调用,变量为null时不会执行dispose tabController?.dispose(); super.dispose(); } // 其余使用tabController的地方,加!非空断言即可 Widget getTabBar() { return TabBar(controller: tabController!, tabs: [ Tab(text: "Add", icon: Icon(Icons.add)), Tab(text: "Edit", icon: Icon(Icons.edit)), Tab(text: "Delete", icon: Icon(Icons.delete)), ]); } Widget getTabBarPages() { return TabBarView(controller: tabController!, children: <Widget>[ Container(color: Colors.red), Container(color: Colors.green), Container(color: Colors.blue) ]); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( flexibleSpace: SafeArea( child: getTabBar(), ), ), body: getTabBarPages()); } }
原错误原因说明
- 直接声明非空类型不加
late:Dart空安全要求非空实例变量必须在声明时、构造函数初始化列表中完成赋值,initState是构造完成后才执行的生命周期方法,编译器无法识别这里的赋值逻辑,因此报错。 - 可空类型直接调用方法:编译器无法保证调用时变量一定不为空,因此禁止直接调用方法,必须通过空断言
!、空安全调用?、判空分支的方式处理空情况。
内容的提问来源于stack exchange,提问作者Noraddeen
相关产品推荐
相关产品推荐

