I currently have
Navigator.pushReplacementNamed(context, "/second", arguments: contact);
...
How would one rewrite this as a MaterialPageRoute?
Contact contact = ModalRoute.of(context).settings.arguments;
.
'/second': (BuildContext context) => ViewContact(),
Yes We can do this by passing the name in the route setting parameter of material page route. Please refer to the following piece of code:
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => VendorDetailScreen(widget.vendor),//pass any arguments
settings: RouteSettings(name: "vendorScreen")),//assign a name for the screen
In this way we can assign the name to the material page route. Now your navigation stack will have a route with the name "vendorScreen" after you push the screen.
You can use a MaterialPageRoute passing contact as argument in this way:
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (BuildContext context) => ViewContact(contact)));
}
And then in the ViewContact page:
class ViewContact extends StatelessWidget {
Contact contact;
ViewContact(this.contact);
...
}
I think that you were asking for something like that:
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ViewContact(contact),
),
);
Just use pushNamed/pushReplacementNamed.
Related
I am trying to get the name of the screen to navigate to as a string(in a custom class), when clicking a button.
class myButton extends StatelessWidget {
String button_txt = '';
String nextPage = '';
double height_ = 39;
myButton(button_txt) {
this.button_txt = button_txt;
this.nextPage = nextPage;
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.pushReplacement(context, '/$nextPage');
},
If you want to use named routes you should use it like this:
Navigator.pushReplacementNamed(context, 'nextPage');
but if you don't want to use named routes there is different way to navigate:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return routewidget;
},
),
);
There are two ways to do this:
use Navigator.pushNamedReplacement(context, '/$nextPage')
use Navigator.pushReplacement(context, route); with a Route Parameter
If you want to use named routes, then use
Navigator.pushNamedReplacement(context, '/name/of/route).
If it still doesn't work, then you might not have set up navigation properly.
If you want to use non-named routes, then the approach will be different:
Navigator.pushReplacement(
context,
MaterialPageRoute( // Material page route makes it
// slide from the bottom to the top
//
// If you want it to slide from the right to the left, use
// `CupertinoPageRoute()` from the cupertino library.
//
// If you want something else, then create your own route
// https://flutter.dev/docs/cookbook/animation/page-route-animation
builder: (context) {
return NextPageWidget();
},
),
);
I am new to Flutter and as I was reading through the tutorial I saw the following code snippet:
// Within the `FirstRoute` widget
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
}
Why does the call in the MaterialPageRoute work? I see it requests an object of type WidgetBuilder, but what we pass is a BuildContext. Do the parentheses around context indicate a call to the constructor of the WidgetBuilder?
The builder parameter accepts an object of type WidgetBuilder as you say. What is "hidden" is that it is typedef:
typedef WidgetBuilder = Widget Function(BuildContext context);
So what you've passed is actually an anonymous function that match it.
It is called an arrow function. Actually this piece of code
(context) => SecondRoute()
can be rewritten like:
MaterialPageRoute(builder: (context) {
return SecondRoute();
})
And widget builder is a function, which MaterialPageRoute require as a parameter.
I need to be able to pop back two pages. As I'm creating pages on the fly using a named route wouldn't be practical. So is there a way to pass context from the original page to the destination page?
On the original page I have;
Navigator.push(
context,
MaterialPageRoute(builder: (originalcontext) => SecondRoute()),
);
Then on that SecondRoute's page I have:
Navigator.push(
context,
MaterialPageRoute(builder: (originalcontext) => ThirdRoute()),
);
Then on the ThirdRoute page, I'd like to pop back to the original page - bypassing the SecondRoute page.
Navigator.pop(originalcontext);
You can define your SecondRoute like this :
class SecondRoute extends StatelessWidget
{
final BuildContext originalContext;
//other properties
SecondRoute({this.originalContext}); //Initialize other properties
//Now use the 'originalContext'
}
Similarly you can define your ThirdRoute .
Now pass the originalContext ,
Navigator.push(
context,
MaterialPageRoute(builder: (originalcontext) => SecondRoute(originalContext:originalcontext)),
);
Edit : The original question has been edited.
First Method:
Try this :
Navigator.of(context).popUntil((route) => route.isFirst)
put the above code on your
ThirdRoute()
Second Method :
put this on your SecondRoute()
Navigator.pushReplacement(context, MaterialPageRoute(builder: (BuildContext context) => ThirdRoute()));
instead of plain Navigator.push(...);
And on your ThirdRoute() add this
Navigator.of(context).pop();
I can see that MaterialApp app can receive routes.
1. Static routing
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
'/page1': (context) => Page1(title: "Main page"),
...
And show them from the widgets like:
myKey.currentState.pushNamed("/page1");
There are other parameters like onGenerateRoute and initialRoute which confuse me more.
2. Dynamic Pages
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
}
Question
Im wondering what is the implication of this parameters and letting this "responsibility" to the MaterialApp, and why we should do it, maybe something related to memory management or how the Widget lifecycle works, or what?
What are the differences between 1. and 2.?
The answer lies more in your architecture than anything.
1. Static Routing is the better of the two in terms of managing a projects complexity. Routes are clearly defined for multiple developers to understand, and the navigation code is much easier, Navigator.of(context).pushNamed('your-route'); vs
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
2. Dynamic Pages is commonly in tutorials and such to reduce boilerplate code. It is merely a shortcut to navigate. The downside of this is it becomes hard to manage routes, and so should be limited to short tutorials.
3. Generated Routes There is a third option though, that in my opinion is the best of the two, and that is a Generated Routes. This is the cleanest and easiest to mantain structure. There is a great tutorial here about it. Here is the rundown:
Declare Routes:
class RoutePaths {
static const Start = '/';
static const SecondScreen = 'second'
}
Declare your router:
class Router {
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case RoutePaths.Start:
return MaterialPageRoute(builder: (_) => YourFirstScreenWidget());
case RoutePaths.SecondScreen:
// you can do things like pass arguments to screens
final event = settings.arguments as Event;
return MaterialPageRoute(
builder: (_) => YourSecondScreenWidget(event: event));
default:
return MaterialPageRoute(
builder: (_) => Scaffold(
body: Center(
child: Text('No route defined for ${settings.name}'),
),
));
}
}
}
Declare it in main.dart
initialRoute: RoutePaths.Start,
onGenerateRoute: Router.generateRoute,
Navigate
// arguments: event is an optional parameter to send to secondScreen
Navigator.of(context).pushNamed(RoutePaths.SecondScreen, arguments: event);
I want to navigate into one page to another an I used following code to that
Create route
final routes = <String,WidgetBuilder> {
DashboardIesl.tag : (context)=>DashboardIesl()
};
navigation to button click
onPressed: () {
Navigator.push(context, new MaterialPageRoute(
builder: (context) => new DashboardIesl()
));
},
It gives the error message as follows
Undefined name 'context'.
please show me more code,context is only available in statefull widgets,
onPressed: () { Navigator.push(
context,
MaterialPageRoute(builder: (context) => DashboardIesl()), );}
I think this will help you
You have to write onPressed() with in the class.