需求
我们在开发应用中,经常会出现一个界面跳转到另外一个界面并带有参数传递,在Android中大家都知道使用Intent传递参数,在第二个Activity中onCreate中可以获取到这个参数。
实现
那么在Flutter中,我们经常会使用路由跳转到另外一个界面,那么如果这个时候需要传参。
代码如下:
/// 路由跳转并带参数 Navigator.pushNamed( context, RouteConst.routeNext, arguments: (TestArguments("一笑轮回", "江苏省徐州市")), ); /// 测试数据模型 class TestArguments { String? name; String? address; TestArguments(this.name, this.address); }
赋值arguments字段
没错,直接赋值arguments字段就可以了,那么我们如何获取呢?
在第二个页面中
class TwoPage extends StatelessWidget { @override Widget build(BuildContext context) { // 从路由设置中获取传递的参数 var arguments = ModalRoute.of(context)?.settings.arguments; // 其他部分的代码... } }
我们需要通过 ModalRoute.of(context)?.settings.arguments获取数据,那么我们直接在 initState方法中直接通过 ModalRoute.of(context)?.settings.arguments获取,会报错
这里出错原因,可以通过错误并查看源码可知,这里部讲述。
我们有的时候需要在initState方法中获取数据并处理一些事情,我们应该怎么做呢?
下面提供一个小技巧。
路由定义
class RouteConst { static const routeNext = "/route_next"; } class RoutePathConst { static var routePaths = <String, Widget Function(BuildContext context)>{ RouteConst.routeNext: (context) => ArgumentsNextPage(), }; }
跳转代码
Navigator.pushNamed( context, RouteConst.routeNext, arguments: (TestArguments("一笑轮回", "江苏省徐州市")), ); /// 测试数据模型 class TestArguments { String? name; String? address; TestArguments(this.name, this.address); }
定义ArgumentsMixin
/// Arguments参数数据 mixin ArgumentsMixin { late final Object? arguments; } /// 路由拼接的参数数据 mixin RouteQueryMixin { final Map<String, String> routeParams = HashMap(); }
重写onGenerateRoute
void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( ... onGenerateRoute: (settings) { var uri = Uri.parse(settings.name ?? ""); var route = uri.path; var params = uri.queryParameters; if (!RoutePathConst.routePaths.containsKey(route)) { return null; } return MaterialPageRoute( builder: (context) { var widgetBuilder = RoutePathConst.routePaths[route]; var widget = widgetBuilder!(context); if (widget is RouteQueryMixin) { (widget as RouteQueryMixin).routeParams.addAll(params); } if (widget is ArgumentsMixin) { (widget as ArgumentsMixin).arguments = settings.arguments; } return widget; }, settings: settings, ); }, ); } }
创建ArgumentsNextPage
///第二页 class ArgumentsNextPage extends StatefulWidget with ArgumentsMixin, RouteQueryMixin { ArgumentsNextPage({super.key}); @override State<ArgumentsNextPage> createState() => _ArgumentsNextPageState(); } class _ArgumentsNextPageState extends State<ArgumentsNextPage> { /// 传参数据文本 String get result { // Arguments传参数据 TestArguments? arguments; if (widget.arguments != null && widget.arguments is TestArguments) { arguments = widget.arguments as TestArguments; } // 路由拼接的数据 var params = widget.routeParams; // 拼接结果数据 return "arguments:name=${arguments?.name ?? ""} address=${arguments?.address ?? ""} \nrouteParams=$params"; } @override void initState() { super.initState(); print("result=$result}"); } @override Widget build(BuildContext context) { return Scaffold( appBar: XYAppBar( title: "第二页", onBack: () { Navigator.pop(context); }, ), body: Center( child: Text(result), ), ); } }
这样就OK了,好像没讲啥,直接看代码吧。
详细代码见: