我有一个StatefulWidget我想在命名路由中使用的。我必须按照https://flutter.dev/docs/cookbook/navigation/navigate- with-arguments的建议传递一些参数,即
StatefulWidget
Navigator.pushNamed( context, routeName, arguments: <args>, );
现在,我需要在状态initState方法中访问这些参数,因为需要这些参数来订阅某些外部事件。如果将args = ModalRoute.of(context).settings.arguments;呼叫放入initState,则会收到运行时异常。
initState
args = ModalRoute.of(context).settings.arguments;
20:49:44.129 4 info flutter.tools I/flutter ( 2680): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ 20:49:44.129 5 info flutter.tools I/flutter ( 2680): The following assertion was thrown building Builder: 20:49:44.129 6 info flutter.tools I/flutter ( 2680): inheritFromWidgetOfExactType(_ModalScopeStatus) or inheritFromElement() was called before 20:49:44.130 7 info flutter.tools I/flutter ( 2680): _CourseCohortScreenState.initState() completed. 20:49:44.130 8 info flutter.tools I/flutter ( 2680): When an inherited widget changes, for example if the value of Theme.of() changes, its dependent 20:49:44.131 9 info flutter.tools I/flutter ( 2680): widgets are rebuilt. If the dependent widget's reference to the inherited widget is in a constructor 20:49:44.131 10 info flutter.tools I/flutter ( 2680): or an initState() method, then the rebuilt dependent widget will not reflect the changes in the 20:49:44.131 11 info flutter.tools I/flutter ( 2680): inherited widget. 20:49:44.138 12 info flutter.tools I/flutter ( 2680): Typically references to inherited widgets should occur in widget build() methods. Alternatively, 20:49:44.138 13 info flutter.tools I/flutter ( 2680): initialization based on inherited widgets can be placed in the didChangeDependencies method, which 20:49:44.138 14 info flutter.tools I/flutter ( 2680): is called after initState and whenever the dependencies change thereafter. 20:49:44.138 15 info flutter.tools I/flutter ( 2680): 20:49:44.138 16 info flutter.tools I/flutter ( 2680): When the exception was thrown, this was the stack: 20:49:44.147 17 info flutter.tools I/flutter ( 2680): #0 StatefulElement.inheritFromElement.<anonymous closure> (package:flutter/src/widgets/framework.dart:3936:9) 20:49:44.147 18 info flutter.tools I/flutter ( 2680): #1 StatefulElement.inheritFromElement (package:flutter/src/widgets/framework.dart:3969:6) 20:49:44.147 19 info flutter.tools I/flutter ( 2680): #2 Element.inheritFromWidgetOfExactType (package:flutter/src/widgets/framework.dart:3285:14) 20:49:44.147 20 info flutter.tools I/flutter ( 2680): #3 ModalRoute.of (package:flutter/src/widgets/routes.dart:698:46) 20:49:44.147 21 info flutter.tools I/flutter ( 2680): #4 _CourseCohortScreenState.initState.<anonymous closure> (package:esk2/cohort_screen.dart:57:23)
我不想将该逻辑放入build方法中,因为它build可能被多次调用,并且初始化只需发生一次。我可以将整个逻辑放在带有boolean isInitialized标志的块中,但这似乎并不是正确的方法。截至目前,该要求/案例是否不受支持?
build
使用如下MaterialApp.onGenerateRoute属性:
MaterialApp.onGenerateRoute
onGenerateRoute: (RouteSettings settings) { print('build route for ${settings.name}'); var routes = <String, WidgetBuilder>{ "hello": (ctx) => Hello(settings.arguments), "other": (ctx) => SomeWidget(), }; WidgetBuilder builder = routes[settings.name]; return MaterialPageRoute(builder: (ctx) => builder(ctx)); },
现在您可以简单地使用NavigatorState.pushNamed:
NavigatorState.pushNamed
Navigator.of(context).pushNamed("hello", arguments: "world");
在这里,您有一些测试Hello小部件:
Hello
class Hello extends StatelessWidget { final String greet; Hello(this.greet); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: Center( child: Text( 'hello $greet', textScaleFactor: 5.0, ), ), ); } }