从Dart常量列表切换到JSON,如何实现列表合并与页面传参?
问题解决指南
一、JSON数据的列表合并实现
从JSON读取的数据本质是List<dynamic>或Map<String, dynamic>,和Dart原生列表用法一致,直接用扩展运算符即可合并,只需注意类型转换:
Future<void> handleNavigate() async { final String response = await rootBundle.loadString('assets/json.json'); final data = json.decode(response); // 合并aList和bList,写法和原生Dart一致 final abList = [...(data['aList'] as List), ...(data['bList'] as List)]; // 合并所有列表 final allList = [...(data['aList'] as List), ...(data['bList'] as List), ...(data['cList'] as List)]; // 后续导航逻辑 }
关键细节:
- JSON解析出的列表默认是
List<dynamic>,如果UserPicked需要List<Map<String, dynamic>>类型,可通过cast转换:(data['aList'] as List).cast<Map<String, dynamic>>() - 由于JSON读取是异步运行时操作,无法用
const修饰合并后的列表,需去掉原代码中的const关键字。
二、正确传递JSON数据到UserPicked页面
原代码存在两个核心问题:导航逻辑未放在异步方法内、误用const修饰运行时数据,修正后的完整代码如下:
// 封装读取JSON+导航的方法 Future<void> navigateToUserPicked() async { try { final String response = await rootBundle.loadString('assets/json.json'); final Map<String, dynamic> data = json.decode(response) as Map<String, dynamic>; // 按需合并并转换类型 final List<Map<String, dynamic>> abList = [ ...(data['aList'] as List).cast<Map<String, dynamic>>(), ...(data['bList'] as List).cast<Map<String, dynamic>>() ]; // 检查context状态,避免Widget销毁后触发导航 if (!context.mounted) return; Navigator.push( context, MaterialPageRoute( builder: (context) => UserPicked(userchoise: abList), // 去掉const ), ); } catch (e) { // 捕获JSON读取失败的异常,比如文件不存在、格式错误 print('读取JSON失败: $e'); } } // 在按钮点击等事件中调用 onTap: () => navigateToUserPicked(),
三、Dart常量列表 vs JSON方案的选择建议
选Dart常量列表的场景:
- 数据固定不变,无需动态修改
- 编译期可确定数据,需要
const优化性能 - 数据量小,直接写在代码里不影响可读性
选JSON方案的场景:
- 数据需要动态更新(比如后续从服务器拉取、本地修改保存)
- 数据量大,写在代码里会导致文件臃肿、可读性差
- 需要多平台共享数据(比如和iOS/Android原生共用JSON文件)
- 后续需本地化、多语言适配,JSON更易维护
额外注意事项
- 确保
UserPicked的userchoise参数类型和传递的数据类型匹配,必要时强制类型转换 - 异步操作必须加异常捕获,避免读取失败导致崩溃
- 跳转前检查
context.mounted,防止Widget销毁后触发无效导航
内容的提问来源于stack exchange,提问作者Miguel
相关产品推荐
相关产品推荐

