With only one codebase, Flutter, Google’s UI toolkit, simplifies the process of developing stunning natively built desktop, web, and mobile applications. Moving between displays and transferring data across them is a regular activity in app development. We’ll look at passing arguments between screens in Flutter in this blog article.
1. Basic Navigation in Flutter
Before diving into passing arguments, let’s quickly review how to navigate between screens in Flutter. Navigation in Flutter is managed using a Navigator
widget and Routes
. Here’s a simple example of navigating from one screen to another:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Navigation Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: FirstScreen(),
);
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
},
child: Text('Go to Second Screen'),
),
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Screen'),
),
body: Center(
child: Text('Welcome to the second screen!'),
),
);
}
}
2. Passing Arguments Using Navigator.push
To pass arguments to a screen, you can use the Navigator.push
method along with the MaterialPageRoute
constructor. Here’s how you can modify the above example to pass data to the SecondScreen
:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Navigation Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: FirstScreen(),
);
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(data: 'Hello from the first screen!'),
),
);
},
child: Text('Go to Second Screen'),
),
),
);
}
}
class SecondScreen extends StatelessWidget {
final String data;
SecondScreen({required this.data});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Screen'),
),
body: Center(
child: Text(data),
),
);
}
}
In this example, we pass a string from FirstScreen
to SecondScreen
using the data
parameter.
3. Using Named Routes for Passing Arguments
Flutter also supports named routes, which can make it easier to manage navigation in larger applications. To pass arguments using named routes, you’ll need to define the routes and use the onGenerateRoute
property. Here’s an example:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Navigation Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// Define routes
initialRoute: '/',
routes: {
'/': (context) => FirstScreen(),
'/second': (context) => SecondScreen(),
},
onGenerateRoute: (settings) {
if (settings.name == '/second') {
final args = settings.arguments as String;
return MaterialPageRoute(
builder: (context) {
return SecondScreen(data: args);
},
);
}
return null;
},
);
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pushNamed(
context,
'/second',
arguments: 'Hello from the first screen!',
);
},
child: Text('Go to Second Screen'),
),
),
);
}
}
class SecondScreen extends StatelessWidget {
final String data;
SecondScreen({required this.data});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Screen'),
),
body: Center(
child: Text(data),
),
);
}
}
In this example, we use named routes and the arguments
property to pass data between screens.
4. Passing Complex Objects Between Screens
In addition to simple data types like strings, you can pass complex objects between screens. Here’s an example:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Navigation Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
'/': (context) => FirstScreen(),
'/second': (context) => SecondScreen(),
},
onGenerateRoute: (settings) {
if (settings.name == '/second') {
final args = settings.arguments as ScreenArguments;
return MaterialPageRoute(
builder: (context) {
return SecondScreen(
title: args.title,
message: args.message,
);
},
);
}
return null;
},
);
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pushNamed(
context,
'/second',
arguments: ScreenArguments(
'Hello from the first screen!',
'This is a message.',
),
);
},
child: Text('Go to Second Screen'),
),
),
);
}
}
class SecondScreen extends StatelessWidget {
final String title;
final String message;
SecondScreen({required this.title, required this.message});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Text(message),
),
);
}
}
class ScreenArguments {
final String title;
final String message;
ScreenArguments(this.title, this.message);
}
In this example, we define a ScreenArguments
class to hold the data we want to pass between screens.
Conclusion
Passing arguments between screens in Flutter is straightforward and flexible. Whether you’re passing simple data types or complex objects, Flutter’s navigation system provides the tools you need. By using Navigator.push
, Navigator.pushNamed
, and named routes, you can efficiently manage navigation and data transfer in your Flutter applications.