Flutter空安全迁移后UI调用函数传参报错如何解决
Flutter 空安全迁移传参报错修复
问题背景
项目进行全量 null safety(空安全)迁移时,业务函数与UI层的调用链路出现报错,升级Flutter版本前所有代码均可正常运行。
升级前旧版代码
跳转唤起弹窗函数
void goToNewItemView() async { final slider= await showDialog<String>( context: context, builder: (context) => NewTodo(), ).then((title){ if(title != null) { addItem(Todo_bis(title: title)); _saveData(); } }); }
UI层按钮调用代码
Align( alignment: Alignment.bottomCenter, child : new RawMaterialButton( onPressed: () { goToNewItemView(); }, child: new Icon( Icons.add, color: Color(0xffff9a7b), size: 30.0, ), shape: new CircleBorder(), elevation: 4.0, fillColor: Colors.white, padding: const EdgeInsets.all(10.0), ), )
弹窗组件NewTodo旧代码
class NewTodo extends StatefulWidget { final Todo item; NewTodo({this.item }); @override _NewTodoState createState() => _NewTodoState(); } class _NewTodoState extends State<NewTodo> { // 其余业务逻辑 }
适配空安全时的报错流程
- 初始适配时,为NewTodo组件的item参数添加
required this.item修饰以符合空安全规范 - 修改完成后,
goToNewItemView()函数提示调用NewTodo缺少参数,于是为该函数新增item形参,在函数内调用NewTodo时传入item参数,修改后的函数代码如下:
void goToNewItemView(item) async { final slider= await showDialog<String>( context: context, builder: (context) => NewTodo(item:item), ).then((title){ if(title != null) { addItem(Todo_bis(title: title)); _saveData(); } }); }
- 上述修改完成后,UI层onPressed回调中的
goToNewItemView();调用提示需要传入参数,不传参会抛出如下错误:
1 positional argument(s) expected, but 0 found
尝试直接传入item参数、使用命名参数形式goToNewItemView(item: item);调用均无法解决报错,此时对应UI层、NewTodo组件代码如下:
// UI层代码 Align( alignment: Alignment.bottomCenter, child : new RawMaterialButton( onPressed: () { goToNewItemView(); }, child: new Icon( Icons.add, color: Color(0xffff9a7b), size: 30.0, ), shape: new CircleBorder(), elevation: 4.0, fillColor: Colors.white, padding: const EdgeInsets.all(10.0), ), )
// NewTodo组件代码 class NewTodo extends StatefulWidget { final Todo item; NewTodo({required this.item }); @override _NewTodoState createState() => _NewTodoState(); } class _NewTodoState extends State<NewTodo> { // 其余业务逻辑 }
最终解决方案
将NewTodo组件中的final Todo item;修改为final Todo? item;,即可移除required this.item中的required修饰符,后续所有调用无需额外传入参数即可正常运行。
修正后的NewTodo组件核心代码:
class NewTodo extends StatefulWidget { final Todo? item; NewTodo({this.item}); @override _NewTodoState createState() => _NewTodoState(); } class _NewTodoState extends State<NewTodo> { // 其余业务逻辑 }
内容的提问来源于stack exchange,提问作者Nitneuq
相关产品推荐
相关产品推荐

