Flutter 含两种必选构造器的Widget路由参数解析最优实现问询
问题解答
1. 原有写法是否可以正常运行?
不能正常运行,存在两个核心问题:
- 强制类型转换会抛出异常:
settings.arguments只能是其中一种类型,当你传入的是Workout类型对象时,执行settings.arguments as Exercice?会直接抛出_CastError类型转换异常,反之同理。 - 缺少return语句:两个分支里创建的
MaterialPageRoute都没有被return,会触发路由方法返回空的运行时错误。
2. 优雅简洁的实现方案
直接用Dart内置的is类型判断运算符,既可以安全校验类型,还能自动完成类型提升,不需要额外强转:
class NavigationRouter { static Route<dynamic> generateRoute(RouteSettings settings) { switch (settings.name) { // ... 其他路由case case oneRmSetupView: final args = settings.arguments; if (args is Exercice) { return MaterialPageRoute(builder: (_) => OneRmSetupView.exercice(exercice: args)); } else if (args is Workout) { return MaterialPageRoute(builder: (_) => OneRmSetupView.workout(workout: args)); } // 参数不匹配时返回错误页 return MaterialPageRoute(builder: (_) => const Scaffold(body: Text('Invalid arguments for OneRmSetupView'))); // ... 其他路由case default: return MaterialPageRoute(builder: (_) => const Scaffold(body: Text('Error'))); } } }
如果要进一步规范参数传递、降低后续维护成本,还可以自定义路由参数类统一管理传参:
// 定义统一参数类 class OneRmSetupArgs { final Workout? workout; final Exercice? exercice; OneRmSetupArgs.workout(this.workout) : exercice = null; OneRmSetupArgs.exercice(this.exercice) : workout = null; } // 跳转时传参 Navigator.pushNamed(context, oneRmSetupView, arguments: OneRmSetupArgs.workout(yourWorkout)); // 路由接收逻辑 case oneRmSetupView: final args = settings.arguments as OneRmSetupArgs; if (args.exercice != null) { return MaterialPageRoute(builder: (_) => OneRmSetupView.exercice(exercice: args.exercice!)); } else { return MaterialPageRoute(builder: (_) => OneRmSetupView.workout(workout: args.workout!)); }
内容的提问来源于stack exchange,提问作者tomcajot
相关产品推荐
相关产品推荐

