Reputation: 1
Can some one help me with Flutter.
I'm trying to (Navigate to a new screen and back.)
Follow the guide here:
https://flutter.dev/docs/cookbook/navigation/navigation-basics
But i got this error here:
Another exception was thrown: Navigator operation requested with a context that does not include a Navigator.
Here is my Simple Flutter code:
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 new MaterialApp(
title: 'Welcome',
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to view by view'),
),
body: Center(
child: Wrap(
children: <Widget>[
RaisedButton(
child: Text('View 2'),
onPressed: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
)
],
),
),
)
);
}
}
class SecondRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
Thanks!
Upvotes: 0
Views: 3116
Reputation: 3676
Yes, in the flutter example MaterialApp is
runApp(MaterialApp(
title: 'Navigation Basics',
home: FirstRoute(),
));
In the Example FirstRoute it's separated from MaterialApp. This is done because if we put the content of FirstRoute directly inside MaterialApp , then it will not have the context of MaterialApp, and it cannot acess the Navigator .
You have 2 options.
Place the Scaffold in it's own stateless Widget .
Or wrap the scaffold in a builder widget to have the MaterialApp context available
class _MyAppState extends State<MyApp>{
@override
Widget build(BuildContext context){
return new MaterialApp(
title: 'Welcome',
debugShowCheckedModeBanner: false,
home: Builder(builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Welcome to view by view'),
),
body: Center(
child: Wrap(
children: <Widget>[
RaisedButton(
child: Text('View 2'),
onPressed: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
)
],
),
),
)})
);
}
}
More info in this answer
Upvotes: 0
Reputation: 1684
Weird that the docs would recommend a broken approach! Just extract the body of the MaterialApp into its own Widget and it will work. Here's the code:
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 new MaterialApp(
title: 'Welcome',
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to view by view'),
),
body: FirstRoute(),
)
);
}
}
class FirstRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Wrap(
children: <Widget>[
RaisedButton(
child: Text('View 2'),
onPressed: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
)
],
),
);
}
}
class SecondRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
Upvotes: 1
Reputation: 329
Wrap the widget which needs to access to Navigator into a Builder or extract that sub-tree into a class. And use the new BuildContext to access Navigator.
Upvotes: 0