Flutter使用restorablePushNamed传参如何满足SerializedMessage序列化要求
报错原因
Navigator.restorablePushNamed 属于路由状态恢复相关API,传递的参数必须可被StandardMessageCodec序列化(仅支持基础类型、Map、List等内置类型),你传递的自定义对象默认不满足序列化要求,因此触发报错。
解决方案
分两种场景处理:
场景1:需要路由状态恢复能力(应用被系统销毁后重启可回到当前详情页)
给你的自定义对象实现序列化逻辑即可,示例如下:
- 改造自定义类,新增
toJson/fromJson方法
class MyObject { final String name; // 其他自定义属性 MyObject({required this.name}); // 转为可序列化的Map结构 Map<String, dynamic> toJson() { return { 'name': name, // 其他属性依次写入 }; } // 从Map恢复自定义对象 static MyObject fromJson(Map<String, dynamic> json) { return MyObject( name: json['name'], // 其他属性依次读取 ); } }
- 传递参数时传入序列化后的结果
ListTile( leading: const FlutterLogo(), title: Text(myObject.name), onTap: () { Navigator.restorablePushNamed( context, ObjectDetailView.routeName, arguments: myObject.toJson()); }, trailing: const Icon(Icons.arrow_forward_ios_rounded), )
- 详情页接收参数时反序列化恢复对象
// 详情页内获取参数 final Map args = ModalRoute.of(context)!.settings.arguments as Map; final MyObject myObject = MyObject.fromJson(args as Map<String, dynamic>);
场景2:不需要路由状态恢复能力
直接替换为普通的Navigator.pushNamed即可,普通路由传参无序列化要求,可直接传递自定义对象,无需额外改造:
onTap: () { Navigator.pushNamed( context, ObjectDetailView.routeName, arguments: myObject); }
关于restorablePushNamed的合理性判断
- 合理场景:你的应用需要支持状态恢复,希望用户切后台后应用被系统回收,再次打开时能直接回到之前浏览的详情页,此时使用
restorablePushNamed符合Flutter最佳实践。 - 不合理场景:不需要状态恢复能力,使用
restorablePushNamed只会增加序列化的额外开发成本,没有必要。
是否需要切换普通push/pop
如果你的应用没有明确的状态恢复需求,直接切换为普通push/pop即可,开发成本更低,完全满足详情页跳转的常规需求。如果有状态恢复需求,不需要切换,按上述序列化方案改造即可。
内容的提问来源于stack exchange,提问作者Tim4497
相关产品推荐
相关产品推荐

