从主屏幕上点击一个按钮后,我开始玩弄颤抖,尝试打开一个新屏幕。我查看了此处之前提出的类似问题,并尝试遵循提供的解决方案,但不确定如何以及在何处实施该解决方案。
这是我得到的例外:
Navigator operation requested with a context that does not include a Navigator.
我想我知道此问题的根本原因,即我要引用的上下文中没有Navigator
小部件,但不确定如何解决。下面是我完整的代码:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
Widget phoneSection = Container(
padding: const EdgeInsets.all(16.0),
child: Row(
children: <Widget>[Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[Container(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
'Welcome To City',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
)
],
),
),
],
),
);
Widget buttonSection = RaisedButton(
child: const Text('Lets Take a Tour'),
color: Theme.of(context).primaryColor,
elevation: 4.0,
splashColor: Colors.blueGrey,
onPressed: () {
Navigator.of(context).pushNamed('/screen2');
},
);
return MaterialApp(
title: 'ATG',
home: Scaffold(
appBar: AppBar(
title: Text('Tour Guide'),
),
body: ListView(
children: <Widget>[Image.asset(
'images/bkm.png',
width: 600.0,
height: 240.0,
fit: BoxFit.cover,
),
phoneSection,
buttonSection,
],
),
),
routes: <String, WidgetBuilder> {
'/screen2' : (BuildContext context) => new Screen2(),
},
);
}
void button1(BuildContext context) {
Navigator.of(context).pushNamed('/screen2');
}
}
class Screen2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text("Screen 2"),
),
),
);
}
}
我正在寻找有关我需要在哪里实现带有代码段的Navigator
小部件引用的输入。感谢您的帮助。
答案 0 :(得分:1)
您在这里做错了几件事。首先是您有多个MaterialApp
实例。您应该永远只有其中之一。
下一个问题是,在您的button1
方法中,您正在使用小部件的上下文来找到Navigator
。但是由于导航器是在该小部件中构建的,因此找不到它。本质上,这是您所使用的上下文:
MyApp <---- Context
MaterialApp
(Navigator)
Scaffold
...
当您执行Navigator.of(context)时,它从当前上下文开始,并向上移动树。
我建议拆分您的应用,以使您拥有一个MyApp小部件(或任何您想调用的名称)广告,然后是每个屏幕的小部件。可以通过使用Builder窗口小部件来实现此目的,但是无论如何,最好将构建函数分开。
这将满足您的需求:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ATG',
home: HomeScreen(),
routes: <String, WidgetBuilder>{
'/screen2': (BuildContext context) => new Screen2(),
},
);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
Widget phoneSection = Container(
padding: const EdgeInsets.all(16.0),
child: Row(
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
'Welcome To City',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
)
],
),
),
],
),
);
Widget buttonSection = RaisedButton(
child: const Text('Lets Take a Tour'),
color: Theme.of(context).primaryColor,
elevation: 4.0,
splashColor: Colors.blueGrey,
onPressed: () {
Navigator.of(context).pushNamed('/screen2');
},
);
return Scaffold(
appBar: AppBar(
title: Text('Tour Guide'),
),
body: ListView(
children: <Widget>[
Image.asset(
'images/bkm.png',
width: 600.0,
height: 240.0,
fit: BoxFit.cover,
),
phoneSection,
buttonSection,
],
),
);
}
void button1(BuildContext context) {
Navigator.of(context).pushNamed('/screen2');
}
}
class Screen2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Screen 2"),
),
);
}
}