Flutter MaterialPageRoute跳转报key必填参数缺失问题排查
Flutter页面跳转key参数缺失问题修复
问题场景
在register_email.dart文件中实现页面跳转与返回功能,使用如下代码:
- push跳转逻辑:
Navigator.push( context, MaterialPageRoute(builder: (context) => WelcomePage()), );
- pop返回逻辑:
Navigator.pop( context, MaterialPageRoute( builder: (context) => LoginPage(), ), );
代码运行到WelcomePage实例化位置时抛出错误:
The named parameter 'key' is required, but there's no corresponding argument. Try adding the required argument
附register_email.dart完整代码:
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:imibonano/pages/loginPhone/welcome_page.dart'; import 'package:imibonano/theme/colors.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:flutter/src/foundation/key.dart'; import 'package:flutter/src/widgets/framework.dart'; import 'package:validators/validators.dart'; class EmailRegisterPage extends StatefulWidget { const EmailRegisterPage({key}) : super(key: key); @override State<EmailRegisterPage> createState() => _EmailRegisterPageState(); } class _EmailRegisterPageState extends State<EmailRegisterPage> { final _formKey = GlobalKey<FormState>(); TextEditingController _email = TextEditingController(); Widget build(BuildContext context) { return Scaffold( appBar: getAppbar(), body: getBody(), ); } Widget getBody() { return ListView( children: [ Column( children: [ Container( margin: const EdgeInsets.only(left: 15.0, right: 8.0), padding: const EdgeInsets.only(left: 25, top: 30), width: 350, child: Text( "你的邮箱是什么", style: TextStyle( color: black, fontSize: 30, fontWeight: FontWeight.bold, ), ), ), Container( margin: EdgeInsets.only(left: 10, right: 20, top: 40), padding: EdgeInsets.only(left: 30, right: 30), child: Text( "请验证你的邮箱,避免丢失账户访问权限", textAlign: TextAlign.left, style: TextStyle( color: Colors.black, fontSize: 20, ), ), ), Container( margin: EdgeInsets.only(right: 40, top: 20, left: 40), child: Form( key: _formKey, child: Column( children: <Widget>[ TextFormField( controller: _email, decoration: InputDecoration( hintText: "输入Email", ), validator: (value) { if (value != null) { if (value.length > 5 && value.contains('@') && value.endsWith('.com')) { return null; } return 'Enter a Valid Email Address'; } }, ), ], ), ), ), SizedBox( height: 50, ), InkWell( borderRadius: BorderRadius.circular(60), onTap: (() async { Navigator.push( context, MaterialPageRoute(builder: (context) => WelcomePage()), ); User? user = FirebaseAuth.instance.currentUser; await FirebaseFirestore.instance .collection('user') .doc(user!.uid) .update({ 'email': _email.text, }); }), child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(60), color: Color.fromARGB(255, 255, 25, 75), ), width: 320, height: 50, child: Center( child: Text( "继续", style: TextStyle( fontWeight: FontWeight.w500, ), ), ), ), ), ], ), ], ); } AppBar getAppbar() { return AppBar( elevation: 0, backgroundColor: white, iconTheme: IconThemeData( color: black, ), ); } }
错误原因
- 核心问题:
WelcomePage的构造函数将key定义为了必填命名参数,实例化时未传值触发报错。同时当前编写的EmailRegisterPage构造函数也存在相同问题:{key}没有声明可空类型,默认属于必填参数。 - 逻辑错误:
Navigator.pop的作用是弹出路由栈顶页面,不需要传入MaterialPageRoute参数,当前写法会导致返回逻辑异常。 - 语法错误:
_formKey作为类成员属性,不需要在@override注解下声明,当前写法属于语法不规范。
修复方案
按以下步骤修改代码即可:
- 修正所有自定义页面(
WelcomePage、EmailRegisterPage、LoginPage)的构造函数,将key设为可选可空参数:- 兼容所有Flutter版本的标准写法:
// 以EmailRegisterPage为例,其他页面替换对应类名即可 const EmailRegisterPage({Key? key}) : super(key: key);- Flutter 3.0+简化写法:
const EmailRegisterPage({super.key}); - 修正pop返回逻辑,删除多余的路由参数:
// 直接调用即可,路由栈会自动返回上一级页面,不需要手动指定LoginPage Navigator.pop(context); - 修正
_formKey的声明位置,去掉多余的@override注解,放到类成员的正确位置。 - 额外优化:当前代码中
Navigator.push执行后立即调用Firebase更新逻辑,建议等页面跳转返回后再执行后续逻辑,避免页面未加载完成就执行异步操作报错,可以改成:onTap: (() async { // 先等待页面跳转返回 await Navigator.push( context, MaterialPageRoute(builder: (context) => const WelcomePage()), ); User? user = FirebaseAuth.instance.currentUser; if(user != null){ await FirebaseFirestore.instance .collection('user') .doc(user.uid) .update({ 'email': _email.text, }); } }),
内容的提问来源于stack exchange,提问作者Didier Supernover
相关产品推荐
相关产品推荐

