我有两个屏幕的应用程序,我想按下按钮从第一个屏幕到第二个屏幕。
屏幕1
import 'package:flutter/material.dart';
import './view/second_page.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MainScreen();
}
}
class MainScreen extends State<MyApp> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text("Title")
),
body: new Center(
child: new FlatButton(child: new Text("Second page"),
onPressed: () {
Navigator.push(context,
new MaterialPageRoute(
builder: (context) => new SecondPage()))
}
)
)
)
);
}
}
屏幕2
import 'package:flutter/material.dart';
class SecondPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new SecondPageState();
}
}
class SecondPageState extends State<SecondPage> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Title"),
),
body: new Center(
child: new Text("Some text"),
),
);
}
}
推动没有发生,我得到了这个
处理手势时抛出以下断言:导航器 请求的操作使用不包含导航器的上下文。 用于从导航器中推送或弹出路由的上下文必须是这样的 作为Navigator小部件后代的小部件。
抛出另一个异常:使用a请求导航器操作 不包含导航器的上下文。
有什么问题?
答案 0 :(得分:10)
将Flutter中的小部件视为树,上下文指向使用构建函数构建的任何节点。在你的情况下,你有
MainScreen <------ context
--> MaterialApp
(--> Navigator built within MaterialApp)
--> Scaffold
--> App Bar
--> ...
--> Center
--> FlatButton
因此,当您使用上下文查找导航器时,您正在使用MainScreen的上下文,该上下文不在导航器下。
您可以创建一个新的Stateless或Stateful Widget子类来包含您的Center + FlatButton,因为其中的构建函数将指向该级别,或者您可以使用Builder并定义{{1回调(具有指向Builder的上下文)以返回Center + FlatButton。
答案 1 :(得分:4)
找不到路线有两个主要原因。
1)路由被定义为传递给Navigator.of(context)的上下文 - @rmtmackenzie解释的场景
2)路线在兄弟分支上定义,例如
Root
-> Content (Routes e.g. Home/Profile/Basket/Search)
-> Navigation (we want to dispatch from here)
如果我们想从Navigation小部件调度路由,我们必须知道对NavigatorState的引用。拥有全局引用非常昂贵,尤其是当您打算在树中移动窗口小部件时。 https://docs.flutter.io/flutter/widgets/GlobalKey-class.html。仅在无法从Navigator.of(上下文)获取它的地方使用它。
在MaterialApp中使用GlobalKey定义navigatorKey
final navigatorKey = GlobalKey<NavigatorState>();
Widget build(BuildContext context) => MaterialApp {
navigatorKey: navigatorKey
onGenerateRoute : .....
};
现在应用程序中您传递navigatorKey的任何地方都可以调用
navigatorKey.currentState.push(....);
刚发布了https://medium.com/@swav.kulinski/flutter-navigating-off-the-charts-e118562a36a5
答案 2 :(得分:1)
仅在主方法中使MaterialApp类成为该示例
void main() => runApp(MaterialApp(home: FooClass(),));
对我来说很好, 我希望它能起作用
答案 3 :(得分:1)
确保在相同的上下文中提及路由表:
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FutureBuilder(future: _isUserLoggedIn(),
builder: (ctx, loginSnapshot) =>
loginSnapshot.connectionState == ConnectionState.waiting ?
SplashScreen() : loginSnapshot.data == true ? AppLandingScreen(): SignUpScreen()
),
routes: {
AppLandingScreen.routeName: (ctx) => AppLandingScreen(),
},
);
}
我遇到了这个问题,因为我用不同的构建方法定义了路由表。
答案 4 :(得分:0)
关于此问题,还有另一种非常不同的解决方法,如果您使用的是警报管理器(Android),然后重新打开您的应用程序。如果导航之前尚未打开屏幕,则导航器将永远无法工作。尽管这是一种罕见的用法,但我认为这应该是一个值得了解的东西。
答案 5 :(得分:0)
是一个新手,已经花了两天的时间来克服Navigtor对象链接到黑屏的问题。
导致此问题的原因是复制的伪数据。找到贝娄两个笨拙的数据块:
**Problematic data **- duplicate assets/image:
_buildFoodItem('assets/plate1.png', 'Salmon bowl', '\$24'),
_buildFoodItem('assets/plate2.png', 'Spring bowl', '\$13'),
_buildFoodItem('assets/plate1.png', 'Salmon bowl', '\$24'),
_buildFoodItem('assets/plate5.png', 'Berry bowl', '\$34'),
**Solution **- after eliminating duplicated image argument:
_buildFoodItem('assets/plate1.png', 'Salmon bowl', '\$24'),
_buildFoodItem('assets/plate2.png', 'Spring bowl', '\$13'),
_buildFoodItem('assets/plate6.png', 'Avocado bowl', '\$34'),
我希望这可以帮助某人、、、、、
答案 6 :(得分:-1)
如果导航器不工作,可能有多种原因,但主要的一个是导航器没有找到上下文。 因此,要解决此问题,请尝试将您的小部件包装在 Builder 中,因为构建器有自己的上下文...