如何解决Flutter中Map类型与Null类型不匹配的错误?
Flutter类型转换错误解决:Expected a value of type 'Map<dynamic, dynamic>', but got one of type 'Null'
问题代码
import 'package:flutter/material.dart'; class Home extends StatefulWidget { const Home({ Key? key }) : super(key: key); @override State<Home> createState() => _HomeState(); } class _HomeState extends State<Home> { Map? data = {}; @override void initState() { super.initState(); } @override Widget build(BuildContext context) { final Map data = ModalRoute.of(context)!.settings.arguments as Map; print(data); return Scaffold( body: SafeArea( child: Padding( padding: const EdgeInsets.fromLTRB(0, 120, 0, 0), child: Column( children: [ TextButton.icon( onPressed: () { Navigator.pushNamed(context,'/location'); }, icon: const Icon(Icons.edit_location), label: const Text('Edit Location'), ), const SizedBox(height: 20,), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( data['location'], style: const TextStyle( fontSize: 20.0, letterSpacing: 2, ), ) ], ), const SizedBox(height: 20,), Text( data['time'], style: const TextStyle( fontSize: 66, ), ), ], ), ), ), ); } }
运行错误
Expected a value of type 'Map<dynamic, dynamic>', but got one of type 'Null'
解决方案
错误根源是直接强制解包ModalRoute.of(context)!并转换为Map,但当路由未传递参数时,settings.arguments会返回Null,触发类型转换失败。以下是两种可行的修正方式:
方式1:添加默认值做防御处理
在获取参数时先判断是否为空,为空则使用预设的默认Map,避免页面崩溃:
import 'package:flutter/material.dart'; class Home extends StatefulWidget { const Home({ Key? key }) : super(key: key); @override State<Home> createState() => _HomeState(); } class _HomeState extends State<Home> { @override Widget build(BuildContext context) { // 安全获取路由参数,为空则使用默认值兜底 final Map? args = ModalRoute.of(context)?.settings.arguments as Map?; final Map data = args ?? { 'location': 'Unknown', 'flag': '', 'time': '00:00' }; print(data); return Scaffold( body: SafeArea( child: Padding( padding: const EdgeInsets.fromLTRB(0, 120, 0, 0), child: Column( children: [ TextButton.icon( onPressed: () { Navigator.pushNamed(context,'/location'); }, icon: const Icon(Icons.edit_location), label: const Text('Edit Location'), ), const SizedBox(height: 20,), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( data['location'], style: const TextStyle( fontSize: 20.0, letterSpacing: 2, ), ) ], ), const SizedBox(height: 20,), Text( data['time'], style: const TextStyle( fontSize: 66, ), ), ], ), ), ), ); } }
方式2:确保跳转时传递参数(配合开发阶段检查)
如果业务逻辑要求页面必须带参数进入,可以在跳转时强制传递参数,同时在页面中添加断言做开发阶段检查:
// 跳转至Home页面时,确保传递参数 Navigator.pushNamed(context, '/home', arguments: { 'location': 'Berlin', 'flag': 'germany.jpg', 'time': '9:08 AM' }); // Home页面的build方法修改 @override Widget build(BuildContext context) { final args = ModalRoute.of(context)?.settings.arguments; // 开发阶段断言,确保参数类型正确 assert(args is Map, "Home页面必须传递Map类型的参数"); final Map data = args as Map; print(data); // 后续页面构建代码不变 }
关键修正点
- 移除
ModalRoute.of(context)!中的强制解包符号!,改用?避免null解包崩溃 - 使用
as Map?做安全类型转换,再通过??提供默认值,保证data始终是非空Map - 可选:用
assert在开发阶段检查参数合法性,提前暴露问题
内容的提问来源于stack exchange,提问作者user21769983
相关产品推荐
相关产品推荐

