I'm trying to make the other page with the button but after debugging this code, the button called 'Next' appears but when I click the button, nothing happens and this error comes in "Navigator operation requested with a context that does not include a Navigator." Could someone help me out? Thank you a lot:)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp(
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
TextEditingController nameController = TextEditingController();
TextEditingController ageController = TextEditingController();
TextEditingController addressController = TextEditingController();
TextEditingController weightController = TextEditingController();
TextEditingController heightController = TextEditingController();
TextEditingController traitController = TextEditingController();
TextEditingController appearanceController = TextEditingController();
String fullName = '';
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.pink,
),
home: Scaffold(
appBar: AppBar(
title: Text('Input Information'),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.purple,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
Navigator.pop(context);
},
),
],
),
),
body: Center(
child: Column(children: <Widget>[
Container(
margin: EdgeInsets.all(20),
child: TextField(
controller: nameController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Full Name',
),
)),
Container(
margin: EdgeInsets.all(20),
child: TextField(
controller: ageController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Age',
),
)),
Container(
margin: EdgeInsets.all(20),
child: TextField(
controller: addressController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Address',
),
)),
Container(
margin: EdgeInsets.all(20),
child: TextField(
controller: weightController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Weight',
),
)),
Container(
margin: EdgeInsets.all(20),
child: TextField(
controller: heightController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Height',
),
)),
Container(
margin: EdgeInsets.all(20),
child: TextField(
controller: traitController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Unique Trait',
),
)),
// Container(
// margin: EdgeInsets.all(20),
// child: TextField(
// controller: appearanceController,
// decoration: InputDecoration(
// border: OutlineInputBorder(),
// labelText: 'Apperance',
// ),
// )),
ElevatedButton(
child: Text('Next'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
),
Container(
margin: EdgeInsets.all(20),
child: Text(fullName),
)
]))),
);
}
}
class SecondRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Camera"),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("Back"))));
}
}
You have to separate MaterialApp. Create separate class for pages.Only then you can able to navigate from one page to another.
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(
theme: ThemeData(
primarySwatch: Colors.pink,
),
home:FirstPage(),
);
}
}
class FirstPage extends StatefulWidget{
@override
_FirstPageState createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
TextEditingController nameController = TextEditingController();
TextEditingController ageController = TextEditingController();
TextEditingController addressController = TextEditingController();
TextEditingController weightController = TextEditingController();
TextEditingController heightController = TextEditingController();
TextEditingController traitController = TextEditingController();
TextEditingController appearanceController = TextEditingController();
String fullName = '';
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text('Input Information'),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.purple,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
Navigator.pop(context);
},
),
],
),
),
body: SingleChildScrollView(
child: Center(
child: Column(children: <Widget>[
Container(
margin: EdgeInsets.all(20),
child: TextField(
controller: nameController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Full Name',
),
)),
Container(
margin: EdgeInsets.all(20),
child: TextField(
controller: ageController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Age',
),
)),
Container(
margin: EdgeInsets.all(20),
child: TextField(
controller: addressController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Address',
),
)),
Container(
margin: EdgeInsets.all(20),
child: TextField(
controller: weightController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Weight',
),
)),
Container(
margin: EdgeInsets.all(20),
child: TextField(
controller: heightController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Height',
),
)),
Container(
margin: EdgeInsets.all(20),
child: TextField(
controller: traitController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Unique Trait',
),
)),
// Container(
// margin: EdgeInsets.all(20),
// child: TextField(
// controller: appearanceController,
// decoration: InputDecoration(
// border: OutlineInputBorder(),
// labelText: 'Apperance',
// ),
// )),
ElevatedButton(
child: Text('Next'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
),
Container(
margin: EdgeInsets.all(20),
child: Text(fullName),
)
])),
));
}
}
class SecondRoute extends StatelessWidget {
// static const String routes = 'second-page';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Camera"),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("Back"))));
}
}
One solution is to wrap your ElevatedButton
in a Builder
widget.
Builder(
builder: (context) => ElevatedButton(
child: Text('Next'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
),
),
This works because your ElevatedButton
is a child of MyApp
widget, not of MaterialApp
widget. MaterialApp
provides a default Navigator
to its children. But, ElevatedButton
is currently a sibling of MaterialApp
, not its child (context wise).
It can be difficult to see this due to the how long & nested Dart code can appear.
Here's another way seeing the code in the question in terms of hierarchy:
main
MyApp(context)
MaterialApp(theme, home, body) ← everything at this level is using MyApp context
Your body:
argument ↑ expanded is ↓:
main
MyApp(context)
MaterialApp(theme, home, body: Center(container x6, ElevatedButton(context)))
... which means ElevatedButton
is getting MyApp context
.
Going down another level:
main
MyApp(context)
MaterialApp(theme, home, body)
Widgets on this level will use MaterialApp context
Wrapping ElevatedButton
in Builder
, pushes ElevatedButton
down a level. That's Builder's
job, to make whatever you give it, children of its context
level.
So with Builder
the above now becomes:
main
MyApp(context)
MaterialApp(theme, home, body: Center(container x6, Builder))
ElevatedButton ← uses MaterialApp context
Navigator.push(context)
is also very easy to misunderstand how it's using the supplied context
. For more background on that, see this answer I wrote for a similar issue, where I explain Navigator.of
in more detail.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.