I have been looking at all the answers on here to pass arguments when doing named route navigation but they seem to be old answers or they don't work.
From what was written it should be working but it doesn't seem to do anything, so I am not sure where my error is.
This is how I have it setup:
Main.dart (With my named routes setup):
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primaryColor: Colors.white,
),
initialRoute: HomePageScreen.id,
routes: {
HomePageScreen.id: (context) => HomePageScreen(),
AddItemScreen.id: (context) => AddItemScreen(),
AdvertiseScreen.id: (context) => AdvertiseScreen(),
HomePageFilterScreen.id: (context) => HomePageFilterScreen(),
HomePageResultsScreen.id: (context) => HomePageResultsScreen(),
ItemPageProfileScreen.id: (context) => ItemPageProfileScreen(),
ItemPageProfileSuggestUpdateScreen.id: (context) => ItemPageProfileSuggestUpdateScreen(),
ItemPageWhereToBuyAddStoreToDatabaseScreen.id: (context) => ItemPageWhereToBuyAddStoreToDatabaseScreen(),
ItemPageWhereToBuyMapScreen.id: (context) => ItemPageWhereToBuyMapScreen(),
ItemPageWhereToBuyScreen.id: (context) => ItemPageWhereToBuyScreen(),
MenuScreen.id: (context) => MenuScreen(),
NotAvailableScreen.id: (context) => NotAvailableScreen(),
TermsScreen.id: (context) => TermsScreen(),
}
);
}
}
HomePageResultsScreen.dart (On button click I am using push named to navigate to the next page, this is working because the new page 'ItemPageProfileScreen is opening):
onTap: () {
Navigator.pushNamed(context, ItemPageProfileScreen.id, arguments: 'MyTestString');
}
ItemPageProfileScreen.dart (I have tried using MaterialApp onGenerateRoute to get the arguments and print to screen to test but it is not working):
class ItemPageProfileScreen extends StatefulWidget {
static const String id = 'item_page_profile_screen';
@override
_ItemPageProfileScreenState createState() => _ItemPageProfileScreenState();
}
class _ItemPageProfileScreenState extends State<ItemPageProfileScreen> {
@override
Widget build(BuildContext context) {
MaterialApp(
onGenerateRoute: (routeSettings){
final arguments = routeSettings.arguments;
print(arguments.toString());
},
);
return Scaffold(),
Thanks for your help.
EDIT Second attempt:
class ItemPageProfileScreen extends StatefulWidget {
final String argument;
ItemPageProfileScreen(this.argument);
static const String id = 'item_page_profile_screen';
@override
_ItemPageProfileScreenState createState() => _ItemPageProfileScreenState();
}
class _ItemPageProfileScreenState extends State<ItemPageProfileScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Text(widget.argument),
There is an official article on how to pass arguments with named routing. https://flutter.dev/docs/cookbook/navigation/navigate-with-arguments
The main idea is pretty straightforward: pass arguments into the constructor of your screen widget.
In the official docs (in the link above) they actually used both approaches with named routing and with regular routing even though the article stated about named routing.
Anyways. Focus on the constructor and arguments.
Where can you access the constructor of your screen with named routing if you pass only the name of the route when you navigate? In onGenerateRoute
method. Let's do it.
Overwrite onGenerateRoute
method in your top screen MyApp (that's where your mistake was). And if you do it you don't need routes: {}
there (your second mistake)
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primaryColor: Colors.white,
),
initialRoute: HomePageScreen.id,
onGenerateRoute: (settings) {
if(settings.name == ItemPageProfileScreen.id) {
String msg = settings.arguments;
return MaterialPageRoute(builder: (_) => ItemPageProfileScreen(msg));
} else if(...
},
Get the arguments from the widget constructor:
class ItemPageProfileScreen extends StatefulWidget {
final String argument;
ItemPageProfileScreen(this.argument);
static const String id = 'item_page_profile_screen';
@override
_ItemPageProfileScreenState createState() => _ItemPageProfileScreenState();
}
class _ItemPageProfileScreenState extends State<ItemPageProfileScreen> {
@override
Widget build(BuildContext context) {
String msg = widget.argument;
...
And sending arguments over on tap:
onTap: () {Navigator.pushNamed(context, ItemPageProfileScreen.id, arguments: 'MyTestString');}
Hope this helps.