How to use MaterialPageRoute with a new file dart?
My codes:
main.dart
import 'package:flutter/material.dart';
import 'package:hello_world/settings_page.dart';
void main() => runApp(Belajar());
class Belajar extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
leading: Icon(Icons.android),
title: Text('Hello World'),
actions: [
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return SettingsPage();
},
),
);
},
)
],
),
),
);
}
}
settings_page.dart
import 'package:flutter/material.dart';
class SettingsPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
),
);
}
}
I tried the code above. But, give me an error:
Navigator operation requested with a context that does not include a Navigator.
What wrong with my code?
you are missing just one thing
MaterialApp(
home:Builder(
//use this context to push new route
builder:(context){
return Scaffold(
appBar://..
);
}
)
)
here builder will introduce a new context which will contain the navigator introduced by material app
First create a class for example runFunction()
and you can use these code for going to that screen
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => runFunction(),
),
);
an example of runFuction
class _recipeSearchState extends State<recipeSearch> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('hello'),
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
Text("Text"),
],
),
),
);
}
}
Related
I was just put official Doc code for see how Navigation work in web(chrome). But when I click button I get an error->
Navigator operation requested with a context that does not include a Navigator.
code->
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('First Route'),
),
body: Center(
child: ElevatedButton(
child: Text('Open route'),
// Within the `FirstRoute` widget
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: ElevatedButton(
// Within the SecondRoute widget
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
Thanks...
I tried to make Dialog function on my app.
But the "No MaterialLocalizations found." error came out and it didn't open the popup window.
I don't know how to solve this issue even though I tried to find other references.
Please let me know how to fix this issue.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
runApp(OverApp());
}
class OverApp extends StatefulWidget {
#override
_OverAppState createState() => _OverAppState();
}
class _OverAppState extends State<OverApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('List'),
),
body: RaisedButton(
child: Text('Show Material Dialog'),
onPressed: _showMaterialDialog,
),
),
);
}
_showMaterialDialog() {
showDialog(
context: context,
builder: (_) => new AlertDialog(
title: new Text("Material Dialog"),
content: new Text("Hey!"),
actions: <Widget>[
FlatButton(
child: Text('Close me!'),
onPressed: () {
Navigator.of(context).pop();
},
)
],
));
}
}
You need to put the MaterialApp in runApp (or make another widget and put the Scaffold in its build and use this new widget as the home of the MaterialApp).
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: OverApp()));
}
class OverApp extends StatefulWidget {
#override
_OverAppState createState() => _OverAppState();
}
class _OverAppState extends State<OverApp> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('List'),
),
body: RaisedButton(
child: Text('Show Material Dialog'),
onPressed: _showMaterialDialog,
),
);
}
_showMaterialDialog() {
showDialog(
context: context,
builder: (_) => new AlertDialog(
title: new Text("Material Dialog"),
content: new Text("Hey!"),
actions: <Widget>[
FlatButton(
child: Text('Close me!'),
onPressed: () {
Navigator.of(context).pop();
},
)
],
));
}
}
Just wonder if I use this code to return PageA from PageD, which function will it get called in PageA?
PageD
Navigator.of(context).popUntil(ModalRoute.withName(PageA.ROUTE));
I would like to make the listView on PageA refreshed once it is back from PageD, but I don't know how to achieve it.
I added a then in PageA, but it is not printing anything.
Navigator.pushNamed(context, PageB.ROUTE).then((onValue) {
print("call from Page4");
_refreshListView();
});
Edit
My project flow is Page A > Page B > Page C > Page D > page A.
All you need to do is return data when you pop PageD and await the data when you push.
This code should help:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
'/' : (context) => PageA(),
'/go': (context) => PageD()
},
);
}
}
class PageA extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page A"),
),
body: Center(
child: ListView(
children: <Widget>[
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: Icon(Icons.forward),
),
);
}
_navigateAndDisplaySelection(BuildContext context) async {
final result = await Navigator.pushNamed(
context,
'/go'
);
if(result){
print(result);
//call the refresh ListView here
_refreshListView();
}
}
}
class PageD extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page D"),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white,),
onPressed: (){
Navigator.pop(context, true);
},
)
),
body: Center(
child: Text("Press back!!"),
),
);
}
}
As to what you explained in the comments... you have to pass arguments from Page D to A when navigating.
Hope this helps.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
'/': (context) => PageA(),
'/b': (context) => PageB(),
'/c': (context) => PageC(),
'/d': (context) => PageD()
},
);
}
}
class PageA extends StatelessWidget {
#override
Widget build(BuildContext context) {
final bool shouldRefresh = ModalRoute.of(context).settings.arguments;
if (shouldRefresh != null) {
print(shouldRefresh);
//call the refresh ListView here
_refreshListView();
}
return Scaffold(
appBar: AppBar(
title: Text("Page A"),
),
body: Center(
child: ListView(
children: <Widget>[],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, '/b');
},
child: Icon(Icons.forward),
),
);
}
}
class PageB extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page B"),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.forward),
onPressed: () {
Navigator.pushNamed(context, '/c');
},
),
);
}
}
class PageC extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page C"),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.forward),
onPressed: () {
Navigator.pushNamed(context, '/d');
},
),
);
}
}
class PageD extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page D"),
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
onPressed: () {
Navigator.pushNamed(context, '/', arguments: true);
},
)),
body: Center(
child: Text("Press back!!"),
),
);
}
}
If you want to go to Page D when you press back in Page A then use this
class PageA extends StatelessWidget {
#override
Widget build(BuildContext context) {
final bool shouldRefresh = ModalRoute.of(context).settings.arguments;
print(shouldRefresh);
return Scaffold(
appBar: AppBar(
title: Text("Page A"),
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
onPressed: () {
Navigator.pushNamed(
context,
'/d',
arguments: true
);
},
),
),
body: Center(
child: ListView(
children: <Widget>[
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, '/b');
},
child: Icon(Icons.forward),
),
);
}
}
i am trying to go on another page using navigation, but i am getting error;
Navigator operation requested with a context that does not include a
Navigator.
i am just trying to move on next page, i followed flutter documentations for this stateless widget but how to do with state full widget.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State createState() => new MyApp1();
}
class MyApp1 extends State<MyApp> {
List<Widget> _listSection = [];
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Share IDEASS',
initialRoute: '/',
routes: {
'/second': (context) => SecondScreen(),
},
home: Scaffold(
appBar: AppBar(
title: Text('IDEAS'),
),
body: Container(
child: Stack(
children: [
floatingButton(),
],
),
),
),
);
}
Widget floatingButton() {
return Container(
padding: const EdgeInsets.all(30),
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, "/SecondScreen");
},
child: Text("+"),
backgroundColor: Colors.blue,
),
);
}
}
class SecondScreen 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!'),
),
),
);
}
}
You should use the named route you created.
Widget floatingButton(BuildContext context) { // added context as a parameter
return Container(
padding: const EdgeInsets.all(30),
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, "/second"); // Changed this to use the named route
},
child: Text("+"),
backgroundColor: Colors.blue,
),
);
}
}
then use the following
body: Container(
child: Stack(
children: [
floatingButton(context),
],
),
),
The situation here is that the floatingButton() uses a context with the navigator to push the given page route. But the context used is provided in the parent Widget(MaterialApp) it self, which doesn't include a Navigator, hence the error.
So, Try this approach:
Separate the Home widget from the MaterialApp, like below:
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Share IDEASS',
initialRoute: '/',
routes: {
'/second': (context) => SecondScreen(),
},
home: HomePage(),
);
Create a stateless widget containing the Scaffold:
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('IDEAS'),
),
body: Container(
child: Stack(
children: [
floatingButton(),
],
),
),
);
}
}
Hope it helps. Let me know if this doesn't work.
You have made two mistakes because of which your code is not working:
You have used wrong route name. Replace /SecondScreen with /second
You have used wrong context. You can get Navigator only if your widget has MaterialApp as it's parent and here you are using context of MyApp1 so it is not working.
Following is a working code for your reference.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State createState() => new MyApp1();
}
class MyApp1 extends State<MyApp> {
List<Widget> _listSection = [];
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Share IDEASS',
initialRoute: '/',
routes: {
'/second': (context) => SecondScreen(),
},
home: AppContent(),
);
}
}
class AppContent extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('IDEAS'),
),
body: Container(
child: Stack(
children: [
floatingButton(context),
],
),
),
);
}
Widget floatingButton(BuildContext context) {
return Container(
padding: const EdgeInsets.all(30),
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, "/second");
},
child: Text("+"),
backgroundColor: Colors.blue,
),
);
}
}
class SecondScreen 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!'),
),
),
);
}
}
I have a side menu created using a Drawer Widget and I want to navigate between the pages in the side menu. I am using Navigator.push() to do so, but for some reason, the page won't change.
The items appear in the side menu, but when clicked on, the page remains the same. Does anyone know how I am misusing Navigator.push()?
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context){
return MaterialApp(
title: 'Grid App',
home: Scaffold(
appBar: AppBar(
title: Text('Grip App'),
),
body: Center(
child: Text('Hello, this is the start page!'),
),
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text("Navigation"),
decoration: BoxDecoration(
color: Colors.grey[700]
),
),
ListTile(
title: Text("First Page"),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FirstPage()),);
},
),
ListTile(
title: new Text("Second Page"),
onTap: () {
Navigator.push(context,
new MaterialPageRoute(builder: (context) => new SecondPage()),);
},
),
],
),
),
),
);
}
}
class FirstPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("First Page"),
),
body: Center(
child: Text("You're on the first page!"),
),
);
}
}
class SecondPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("Second Page"),
),
body: Text("This is the second page"),
);
}
}
Just separate the MaterialApp with another screen. Simply you can right click on the Scaffold widget and select Extract Widget. Give the name to your widget and it will extract your code into another stateless widget.
copy paste this code to dartpad and run it
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context){
return MaterialApp(
title: 'Grid App',
home: NewApp(),
);
}
}
class NewApp extends StatelessWidget {
const NewApp({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Grip App'),
),
body: Center(
child: Text('Hello, this is the start page!'),
),
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text("Navigation"),
decoration: BoxDecoration(
color: Colors.grey[700]
),
),
ListTile(
title: Text("First Page"),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FirstPage()),);
},
),
ListTile(
title: new Text("Second Page"),
onTap: () {
Navigator.push(context,
new MaterialPageRoute(builder: (context) => new SecondPage()),);
},
),
],
),
),
);
}
}
class FirstPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("First Page"),
),
body: Center(
child: Text("You're on the first page!"),
),
);
}
}
class SecondPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("Second Page"),
),
body: Text("This is the second page"),
);
}
}
The Navigator won't work if you're doing in under the MateriaApp context like you are using. Remove MaterialApp widget to main() or make another Widget for That.
Try this :
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(MaterialApp(
home: MyApp(),
));
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text('Grip App'),
),
body: Center(
child: Text('Hello, this is the start page!'),
),
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text("Navigation"),
decoration: BoxDecoration(
color: Colors.grey[700]
),
),
ListTile(
title: Text("First Page"),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FirstPage()),);
},
),
ListTile(
title: new Text("Second Page"),
onTap: () {
Navigator.push(context,
new MaterialPageRoute(builder: (context) => new SecondPage()),);
},
),
],
),
),
);
}
}
class FirstPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("First Page"),
),
body: Center(
child: Text("You're on the first page!"),
),
);
}
}
class SecondPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("Second Page"),
),
body: Text("This is the second page"),
);
}
}
Big problem here is using wrong context.
You can't use App context for Navigator. Take a try with Builder
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Grid App',
home: Builder(
builder: (context) => buildScaffold(context),
),
);
}
Scaffold buildScaffold(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Grip App'),
),
body: Center(
child: Text('Hello, this is the start page!'),
),
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text("Navigation"),
decoration: BoxDecoration(color: Colors.grey[700]),
),
ListTile(
title: Text("First Page"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FirstPage()),
);
},
),
ListTile(
title: new Text("Second Page"),
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new SecondPage()),
);
},
),
],
),
),
);
}
}
Quick Fix
void main() => runApp(MaterialApp(home: MyApp()));
Error You are facing
Your current code gives below error, you can see that in the console too
Error: The following assertion was thrown while handling a gesture:
Navigator operation requested with a context that does not include a Navigator.
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.
You can solve this by taking MaterialApp or Builder