Flutter应用抛出TypeError:Null无法转换为bool类型问题求助
Flutter时区应用构建Home组件时触发_TypeError:
type 'Null' is not a subtype of type 'bool' 运行日志
执行热重启... 正在同步文件到设备TECNO K7... 应用已在4,790毫秒内重启。 D/libc-netbsd( 7099): getaddrinfo: worldtimeapi.org 从代理获取结果 gai_error = 0 I/flutter ( 7099): {abbreviation: EAT, client_ip: 197.239.7.195, datetime: 2022-09-14T12:27:41.758821+03:00, day_of_week: 3, day_of_year: 257, dst: false, dst_from: null, dst_offset: 0, dst_until: null, raw_offset: 10800, timezone: Africa/Kampala, unixtime: 1663147661, utc_datetime: 2022-09-14T09:27:41.758821+00:00, utc_offset: +03:00, week_number: 37} I/flutter ( 7099): {} ======== 组件库捕获到异常 ======================================================= 构建Home(dirty, state: _HomeState#f907f)时抛出如下_TypeError: type 'Null' is not a subtype of type 'bool'
问题根源
Loading页面获取时区数据后,通过Navigator.pushReplacementNamed跳转至Home页面并传递arguments,但Home页面打印显示data为空字典,导致data['dayTime']取值为Null,触发类型转换错误。
核心代码错误
- Home页面的data赋值逻辑完全写反:原代码逻辑为「data为空时保留空值,非空时才读取路由参数」,与预期的「空数据时读取路由参数,非空时保留现有数据」完全相反,导致首次进入Home页面无法获取传递的参数。
- 路由参数未做Null处理:
ModalRoute.of(context)?.settings.arguments可能为Null,直接强制转换为Map会触发异常。 - WordTime类异常处理不完善:网络请求失败时,
dayTime变量未初始化,后续传递会引发未初始化错误。
修复方案
1. 修正Home页面的data赋值逻辑
调整逻辑顺序,同时处理参数为Null的情况:
@override Widget build(BuildContext context) { // 修正逻辑:空数据时读取路由参数,非空则保留现有数据 final routeArgs = ModalRoute.of(context)?.settings.arguments; if (data.isEmpty && routeArgs != null) { data = routeArgs as Map; } print(data); // 增加Null判断,默认设为夜间模式 bool isDayTime = data['dayTime'] ?? false; String bgImage = isDayTime ? 'day.jpg' : 'night.jpg'; // ... 其余代码不变 }
2. 完善WordTime类的异常处理
在catch块中初始化dayTime,避免未初始化错误:
Future<void> getTime() async{ try { Response response= await http.get(Uri.parse('http://worldtimeapi.org/api/timezone/$url')); Map data = jsonDecode(response.body); print (data); String datetime = data['datetime']; String offset = data['utc_offset'].substring(1,3); DateTime now = DateTime.parse(datetime); now= now.add(Duration(hours: int.parse(offset))); time = DateFormat.jm().format(now); dayTime = now.hour >6 && now.hour <20 ? true : false; } catch (e){ print(' the error is $e'); time ='could not get time data'; // 异常时初始化dayTime为默认值 dayTime = false; } }
3. 可选:通过构造函数传递参数(更安全的方式)
避免依赖路由参数的不确定性,直接通过构造函数传递数据:
- 修改Home组件:
class Home extends StatefulWidget { final Map data; const Home({Key? key, required this.data}) : super(key: key); @override State<Home> createState() => _HomeState(); } class _HomeState extends State<Home> { late Map data; @override void initState() { super.initState(); data = widget.data; } // ... 其余代码不变 }
- 修改Loading页面的跳转代码:
// 替换原Navigator.pushReplacementNamed代码 Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => Home( data: { 'location': instance.location, 'flag': instance.flag, 'time': instance.time, 'dayTime': instance.dayTime }, ), ), );
验证修复
修复后,首次进入Home页面会正确获取Loading页面传递的时区数据,data['dayTime']不会为Null;网络请求失败时也能保证dayTime有默认值,彻底避免类型转换错误。
内容的提问来源于stack exchange,提问作者Robert Balinda
相关产品推荐
相关产品推荐

