I'm trying to pass values between routes using Navigator.pushReplacementNamed()
, but I'm not getting it.
I can not figure out what the correct syntax and logic is in which data will exit pushReplacementNamed
and get the routes
key.
Can you help me?
Enter the code below to facilitate understanding:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(),
routes: <String, WidgetBuilder> {
'/form': (BuildContext context) => new FormPage(email: ???, header: {'auth': ???}),
},
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
floatingActionButton: new FloatingActionButton(
onPressed: () {
Navigator.pushReplacementNamed(context, '/form', {email: '[email protected]', header: {'auth': '1234'}});
},
child: new Icon(Icons.navigate_next),
),
);
}
}
class FormPage extends StatefulWidget {
FormPage({Key key, this.email, this.header}) : super(key: key);
String email;
Map header;
@override
FormPageState createState() => new FormPageState();
}
class FormPageState extends State<FormPage> {
@override
Widget build(BuildContext context) {
return new Container(
child: new Column(
children: <Widget>[
new Text(widget.email),
new Text(widget.header['auth'])
],
),
);
}
}
After correction:
The purpose of trying to use pushReplacementNamed
was to remove the route history, so if the user presses the device's back button to get back to the earlier route, the route would no longer exist. Reference
The reason for this implementation is to be used on a login page, if the user has already been authenticated by google sign
he is redirected to the next page passing login parameters and could not return to the login page by device's back button.
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(),
routes: <String, WidgetBuilder> {
'/form': (BuildContext context) => new FormPage(), //new
},
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
floatingActionButton: new FloatingActionButton(
onPressed: () {
Navigator.of(context).pushReplacement( //new
new MaterialPageRoute( //new
settings: const RouteSettings(name: '/form'), //new
builder: (context) => new FormPage(email: '[email protected]', header: {'auth': '1234'}) //new
) //new
); //new
},
child: new Icon(Icons.navigate_next),
),
);
}
}
class FormPage extends StatefulWidget {
FormPage({Key key, this.email, this.header}) : super(key: key);
String email;
Map header;
@override
FormPageState createState() => new FormPageState();
}
class FormPageState extends State<FormPage> {
@override
Widget build(BuildContext context) {
return new Container(
child: new Column(
children: <Widget>[
new Text(widget.email),
new Text(widget.header['auth'])
],
),
);
}
}
A route that blocks interaction with previous routes. ModalRoutes cover the entire Navigator. They are not necessarily opaque, however; for example, a pop-up menu uses a ModalRoute but only shows the menu in a small box overlapping the previous route. The T type argument is the return value of the route.
I think you might be miss understanding how result works. The result goes back to the previous widget that pushed the last route and is using await
for the result of the Future
sent back by the previous call to push
. Do you simply want to start a route with parameters? Then you can do this.
Navigator.of(context).pushReplacement(
new MaterialPageRoute(
settings: const RouteSettings(name: '/form'),
builder: (context) => new FormPage(
email: '[email protected]',
header: {'auth': '1234'},
),
),
);
Navigator.of(context).pushReplacementNamed('/route', arguments: 'Test String');
to pass any object as arguments from first widget.String s = ModalRoute.of(context).settings.arguments;
to parse the arguments after initState()
method, like didChangeDependencies()
or build(BuildContext context)
in the second widget.Eg:
@override
void didChangeDependencies() {
RouteSettings settings = ModalRoute.of(context)!.settings;
if (settings.arguments != null) {
CustomObject obj = settings.arguments as CustomObject;
}
super.didChangeDependencies();
}
Instead of Step 2.
You can also initialize the widget class with those arguments by using onGenerateRoute: (settings) {}
in your App
Widget.
Eg:
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
/*...*/
routes: {
/*Don't add those routes with arguments here..*/
},
onGenerateRoute: (settings) {
if (settings.name == SECOND_SCREEN_ROUTE) {
if (settings.arguments != null) {
CustomObject obj = settings.arguments as CustomObject;
return MaterialPageRoute(
builder: (context) {
return SecondScreen(obj);
},
);
}
}
assert(false, 'Need to implement ${settings.name}');
return null;
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With