Dart 颤振:继承的小部件和路由
我希望在我的应用程序的根目录下有一个继承的小部件,它将包含我的数据提供者,我将在整个应用程序中使用它。所以我有一个继承的小部件,但每次尝试加载它时,我都会得到一个Dart 颤振:继承的小部件和路由,dart,flutter,inherited-widget,Dart,Flutter,Inherited Widget,我希望在我的应用程序的根目录下有一个继承的小部件,它将包含我的数据提供者,我将在整个应用程序中使用它。所以我有一个继承的小部件,但每次尝试加载它时,我都会得到一个getter'data'被调用为null,我不知道为什么 这是我的主要任务。省道: void main() => runApp(new MatAppRoot()); class MatAppRoot extends StatelessWidget { @override Widget build(BuildContext
getter'data'被调用为null,我不知道为什么
这是我的主要任务。省道:
void main() => runApp(new MatAppRoot());
class MatAppRoot extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'MyCoolApp',
routes: <String, WidgetBuilder>{
'Login': (BuildContext context) => new LoginPage(),
'Cool': (BuildContext context) => new CoolPage(),
},
home: new CoolApp(),
);
}
}
class CoolAppextends StatefulWidget {
final Widget child;
CoolApp({this.child});
@override
CoolAppState createState() => new CoolAppState();
static CoolAppState of(BuildContext context) {
return (context.inheritFromWidgetOfExactType(CoolInherit) as CoolInherit).data;
}
}
class CoolAppState extends State<CoolApp> {
String randomString = 'AYEEAS!!!';
@override
void initState() { super.initState();
Navigator.of(context).pushNamedAndRemoveUntil('Login', (Route<dynamic> route) => false);
}
@override
Widget build(BuildContext context) {
return new CoolInherit(
data: this,
child: new LoginPage(),
);
}
}
class CoolInherit extends InheritedWidget {
final CoolAppState data;
CoolInherit({
Key key,
this.data,
Widget child,
}): super(
key: key,
child: child
);
@override
bool updateShouldNotify(CoolInherit old) {
return true;
}
}
在我的Cool
页面中,我尝试在单击以下按钮时加载另一个页面:
if (logInSuccessful) {
Navigator.of(context).pushNamedAndRemoveUntil('Cool', (Route<dynamic> route) => false);
}
viewCoolDetails() {
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new CoolDetailsPage()),
);
}
但是在我的CoolDetailsPage
中,当我这样做时,它崩溃了:
@override
Widget build(BuildContext context) {
final inheritedWidget = CoolApp.of(context);
print(inheritedWidget.randomString); <-- ERROR: The getter 'data' was called on null
return new Text('Cool!');
}
main.dart:56是return(context.inheritFromWidgetOfExactType(CoolInherit)作为CoolInherit)代码>因此,如果我的侦探工作达到了标准,我怀疑这是与导航/上下文有关的,它阻止了我的最终小部件访问继承的小部件,但是我不确定。
更新:
尽我所能,我需要在更高级别插入我的InheritedWidget;在领航员面前。所以我在MaterialApp中插入了这个:
builder: (context, child) {
return new CoolApp(child: child);
},
但这似乎不起作用
E/flutter (32321): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter (32321): Navigator operation requested with a context that does not include a Navigator.
E/flutter (32321): The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.
E/flutter (32321): #0 Navigator.of.<anonymous closure> (package:flutter/src/widgets/navigator.dart:1180:9)
E/flutter (32321): #1 Navigator.of (package:flutter/src/widgets/navigator.dart:1187:6)
E/flatter(32321):[错误:topaz/lib/tonic/logging/dart\u ERROR.cc(16)]未处理的异常:
E/颤振(32321):在不包含导航器的上下文中请求导航器操作。
E/flatter(32321):用于从导航器推送或弹出路由的上下文必须是导航器小部件的后代小部件的上下文。
E/颤振(32321):#0.of。(包:flatter/src/widgets/navigator.dart:1180:9)
E/flatter(32321):#1 Navigator.of(包:flatter/src/widgets/Navigator.dart:1187:6)
这是因为您正试图从另一条路径(动态)访问路径/
中的CoolApp
但在动态路线中,没有CoolApp
。因此CoolApp.of(context)
返回null,因此访问.data
会崩溃
你需要找到一种方法,在你的新路线中有一个CoolApp
实例
有关更多信息,请查看我很久以来都遇到过同样的问题,我意识到如果您使用继承的小部件包装MaterialApp,您的数据可以通过整个应用程序访问。但是在您的情况下,您需要在用户登录后传递数据,以便创建一个新的导航器,并用继承的小部件包装它。您可以看到此项目
这是有道理的。。。这就是我一直坚持的部分。我不知道如何把它引入新路线。我在你提到的另一个问题中看到,他们谈论的是MaterialApp builder
,但不确定在这个场景中我将如何实现它,或者它是否是我所需要的。仍然对此感到困惑。。。似乎在网上找不到任何关于如何以有效的方式执行类似操作的信息…我将builder:(context,child){return new CoolApp(child:child);},
添加到MaterialApp,因为从我所知,这将在导航器之前注入状态。。。但这似乎没有帮助…:(在这里找到了一个很好的方法:http://ericwindmill.com/using-flutter-inherited-widgets-effectively
@Jus10您找到解决方案了吗?您是对的。但是,在我的例子中,如果您希望使用ModalRoute.of(context.settings.arguments
)获取路由参数,则该方法无效。它返回null
E/flutter (32321): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter (32321): Navigator operation requested with a context that does not include a Navigator.
E/flutter (32321): The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.
E/flutter (32321): #0 Navigator.of.<anonymous closure> (package:flutter/src/widgets/navigator.dart:1180:9)
E/flutter (32321): #1 Navigator.of (package:flutter/src/widgets/navigator.dart:1187:6)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'InheritedWidget Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyNav(),
);
}
}
Route generatePage(child) {
return MaterialPageRoute(builder: (context) => child);
}
class MyNav extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MyData(
data: 'omg',
child: Navigator(
onGenerateRoute: (settings) {
switch (settings.name) {
case 'page1':
return generatePage(PageOne());
case 'page2':
return generatePage(PageTwo());
case 'page3':
return generatePage(PageThree());
}
},
initialRoute: 'page1',
),
);
}
}
class MyData extends InheritedWidget {
MyData({Key key, this.child, this.data}) : super(key: key, child: child);
final Widget child;
final String data;
static MyData of(BuildContext context) {
return (context.inheritFromWidgetOfExactType(MyData) as MyData);
}
@override
bool updateShouldNotify(MyData oldWidget) {
return true;
}
}
class PageOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Page 1'),
),
backgroundColor: Colors.red,
body: RaisedButton(
child: Text("Goto page 2, data=${MyData.of(context).data}"),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => PageTwo()));
},
),
);
}
}
class PageTwo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Page 2'),
),
backgroundColor: Colors.red,
body: RaisedButton(
child: Text("Goto page 3, data=${MyData.of(context).data}"),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => PageThree()));
},
),
);
}
}
class PageThree extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Page 3'),
),
backgroundColor: Colors.green,
body: RaisedButton(
child: Text("Goto page 4, data=${MyData.of(context).data}"),
onPressed: null,
),
);
}
}