Flutter添加TabBar时出现Null不是Map<String,Object>子类型转换错误如何解决
报错原因
你在MyHomePage的TabBarView组件中直接实例化了Screen1,此时Screen1是作为Tab的子组件直接渲染,并非通过Navigator.pushNamed路由跳转打开,因此ModalRoute.of(context)!.settings.arguments的返回值为null,你在screen1.dart中直接将null强转为Map<String, Object>就触发了该类型转换错误。
解决办法
方案1:适配双场景(推荐)
修改screen1.dart的参数获取逻辑,增加空判断和默认值,同时支持Tab直接渲染和路由跳转两种场景:
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class Screen1 extends StatelessWidget { void selectScreen(BuildContext ctx){ Navigator.of(ctx).pushReplacementNamed( '/x2', ); } @override Widget build(BuildContext context) { // 新增空判断,参数为空时使用默认值 final Map<String, Object> routeArg = (ModalRoute.of(context)?.settings.arguments as Map<String, Object>?) ?? {'id': 0, 'title': '未传参'}; return Scaffold( appBar: AppBar( title: Text("Screen 1"), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text("Welcome To Screen 1" , style: TextStyle(fontSize: 35)), Text("${routeArg['id']}" , style: TextStyle(fontSize: 30)), Text("${routeArg['title']}" , style: TextStyle(fontSize: 30)), InkWell( child: Text("Go to Screen 2", style: TextStyle(fontSize: 35)), onTap: (){selectScreen(context);}, ), ], ), ), ); } }
方案2:Tab场景也自定义传参
如果Tab下展示的Screen1需要指定固定参数,可以给Screen1增加构造参数传值:
- 先修改screen1.dart,新增可选构造参数:
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class Screen1 extends StatelessWidget { final Map<String, Object>? customArgs; const Screen1({super.key, this.customArgs}); void selectScreen(BuildContext ctx){ Navigator.of(ctx).pushReplacementNamed( '/x2', ); } @override Widget build(BuildContext context) { // 优先取构造传入的参数,其次取路由参数,都为空则用默认值 final Map<String, Object> routeArg = customArgs ?? (ModalRoute.of(context)?.settings.arguments as Map<String, Object>?) ?? {'id': 0, 'title': '未传参'}; return Scaffold( appBar: AppBar( title: Text("Screen 1"), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text("Welcome To Screen 1" , style: TextStyle(fontSize: 35)), Text("${routeArg['id']}" , style: TextStyle(fontSize: 30)), Text("${routeArg['title']}" , style: TextStyle(fontSize: 30)), InkWell( child: Text("Go to Screen 2", style: TextStyle(fontSize: 35)), onTap: (){selectScreen(context);}, ), ], ), ), ); } }
- 再修改main.dart中
TabBarView的Screen1实例,传入自定义参数:
body: TabBarView( children: <Widget>[ Screen1(customArgs: {'id': 1, 'title': 'Tab页Screen1'},), Screen2(), ], ),
内容的提问来源于stack exchange,提问作者Osama Mohamed
相关产品推荐
相关产品推荐

