Sending Information from One Screen to Another in Flutter
Flutter applications commonly contain multiple screens such as Login, Home, Profile, Product Details, Cart, Checkout, Settings, and Confirmation screens. In many applications, one screen needs to send information to another screen while navigating.
For example, when a user selects a product from a product list, the selected product information can be sent to the Product Details screen. Flutter provides several ways to accomplish this, including constructor parameters, route arguments, named-route arguments, and returning data with Navigator.pop().
In Flutter terminology, screens and pages are represented by routes, and the Navigator manages the stack of routes. Flutter Navigation and Routing Documentation
1. What Does Sending Information Between Screens Mean?
Sending information between screens means transferring values or objects from one route to another during navigation.
For example:
Home Screen
|
| User information
v
Profile Screen
The Home Screen may contain information such as:
- User name
- User ID
- Email address
- Profile image
- User role
The Profile Screen receives this information and displays it.
2. Why Do We Need to Send Information Between Screens?
Real-world Flutter applications frequently need to transfer information during navigation.
Scenario |
Information Sent |
|---|
Product List → Product Details |
Product object |
Login → Home |
User name, user ID, token |
Student List → Student Details |
Student object |
Cart → Checkout |
Cart items and total price |
Settings → Profile |
Selected settings |
Form → Confirmation |
Submitted form information |
Category List → Product List |
Category ID or category object |
3. Basic Navigation Flow
A typical information-transfer flow looks like this:
Screen A
|
| Data
| Navigator.push()
v
Screen B
|
| Display / Process Data
v
Screen B UI
Flutter's official navigation cookbook demonstrates sending an object such as a Todo from one screen to a detail screen. Flutter: Send data to a new screen
4. Sending a Simple String
The easiest method is to pass the information through the destination screen's constructor.
First Screen
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
const String userName = 'Manish';
return Scaffold(
appBar: AppBar(
title: const Text('Home Screen'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ProfileScreen(
name: userName,
);
},
),
);
},
child: const Text('Open Profile'),
),
),
);
}
}
Second Screen
class ProfileScreen extends StatelessWidget {
final String name;
const ProfileScreen({
super.key,
required this.name,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Profile'),
),
body: Center(
child: Text(
'Welcome, $name',
style: const TextStyle(
fontSize: 24,
),
),
),
);
}
}
How It Works
- The Home Screen has a variable called
userName.
Navigator.push() opens the Profile Screen.
- The
userName value is passed to the Profile Screen constructor.
- The Profile Screen receives the value through its
name parameter.
- The value is displayed using a
Text widget.
5. Sending Multiple Values
You can send multiple values from one screen to another.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ProfileScreen(
name: 'Manish',
age: 25,
email: '[email protected]',
);
},
),
);
The destination screen can receive these values:
class ProfileScreen extends StatelessWidget {
final String name;
final int age;
final String email;
const ProfileScreen({
super.key,
required this.name,
required this.age,
required this.email,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Profile'),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Name: $name'),
Text('Age: $age'),
Text('Email: $email'),
],
),
),
);
}
}
6. Sending an Integer
Numbers such as IDs, quantities, scores, and counts can also be passed directly.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ProductScreen(
productId: 101,
);
},
),
);
Receive the ID:
class ProductScreen extends StatelessWidget {
final int productId;
const ProductScreen({
super.key,
required this.productId,
});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text(
'Product ID: $productId',
),
),
);
}
}
7. Sending a Boolean Value
Boolean values are useful for passing flags or states.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return AccountScreen(
isPremium: true,
);
},
),
);
Destination screen:
class AccountScreen extends StatelessWidget {
final bool isPremium;
const AccountScreen({
super.key,
required this.isPremium,
});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text(
isPremium
? 'Premium Account'
: 'Free Account',
),
),
);
}
}
8. Sending a Custom Object
For real-world applications, sending a complete model object is often more convenient than sending many individual values.
Create a Product Model
class Product {
final int id;
final String name;
final double price;
final String description;
const Product({
required this.id,
required this.name,
required this.price,
required this.description,
});
}
Create Product Data
final product = Product(
id: 101,
name: 'Flutter Course',
price: 4999,
description: 'Complete Flutter development course.',
);
Send Product to Another Screen
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ProductDetailsScreen(
product: product,
);
},
),
);
Receive Product
class ProductDetailsScreen extends StatelessWidget {
final Product product;
const ProductDetailsScreen({
super.key,
required this.product,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(product.name),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
product.name,
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
Text('Product ID: ${product.id}'),
Text('Price: ₹${product.price}'),
const SizedBox(height: 10),
Text(product.description),
],
),
),
);
}
}
This constructor-based approach is demonstrated in Flutter's official navigation documentation for passing a Todo object to another screen. :contentReference[oaicite:0]{index=0}
9. Sending Data From a List to a Detail Screen
One of the most common examples is sending information from a list item to its detail screen.
class ProductListScreen extends StatelessWidget {
ProductListScreen({super.key});
final List<Product> products = const [
Product(
id: 1,
name: 'Flutter Course',
price: 4999,
description: 'Learn Flutter development.',
),
Product(
id: 2,
name: 'Dart Course',
price: 3999,
description: 'Learn Dart programming.',
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Products'),
),
body: ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
final product = products[index];
return ListTile(
title: Text(product.name),
subtitle: Text('₹${product.price}'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ProductDetailsScreen(
product: product,
);
},
),
);
},
);
},
),
);
}
}
When the user taps a product, the selected product object is sent to the Product Details screen.
10. Sending Information From a Login Screen
After a successful login, an application may need to send basic user information to the Home Screen.
class LoginScreen extends StatelessWidget {
const LoginScreen({super.key});
void login(BuildContext context) {
const String username = 'Manish';
const int userId = 1001;
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return HomeScreen(
username: username,
userId: userId,
);
},
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Login'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
login(context);
},
child: const Text('Login'),
),
),
);
}
}
Home Screen:
class HomeScreen extends StatelessWidget {
final String username;
final int userId;
const HomeScreen({
super.key,
required this.username,
required this.userId,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Welcome, $username'),
Text('User ID: $userId'),
],
),
),
);
}
}
11. Sending Form Data to Another Screen
Forms commonly collect information on one screen and display it on a confirmation screen.
class FormScreen extends StatefulWidget {
const FormScreen({super.key});
@override
State<FormScreen> createState() => _FormScreenState();
}
class _FormScreenState extends State<FormScreen> {
final nameController = TextEditingController();
final emailController = TextEditingController();
@override
void dispose() {
nameController.dispose();
emailController.dispose();
super.dispose();
}
void submitForm() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ConfirmationScreen(
name: nameController.text,
email: emailController.text,
);
},
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Registration'),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
TextField(
controller: nameController,
decoration: const InputDecoration(
labelText: 'Name',
),
),
const SizedBox(height: 15),
TextField(
controller: emailController,
decoration: const InputDecoration(
labelText: 'Email',
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: submitForm,
child: const Text('Submit'),
),
],
),
),
);
}
}
Confirmation Screen
class ConfirmationScreen extends StatelessWidget {
final String name;
final String email;
const ConfirmationScreen({
super.key,
required this.name,
required this.email,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Confirmation'),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Name: $name'),
Text('Email: $email'),
const SizedBox(height: 20),
const Text(
'Registration submitted successfully.',
),
],
),
),
);
}
}
12. Sending a List of Objects
Sometimes an entire collection needs to be transferred to another screen, such as a cart or order summary.
class CartScreen extends StatelessWidget {
final List<Product> products;
const CartScreen({
super.key,
required this.products,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Cart'),
),
body: ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
final product = products[index];
return ListTile(
title: Text(product.name),
subtitle: Text(
'₹${product.price}',
),
);
},
),
);
}
}
Send the list:
final cartItems = <Product>[
product1,
product2,
product3,
];
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return CartScreen(
products: cartItems,
);
},
),
);
13. Sending a Map
A Map can also be passed between screens.
final userData = {
'name': 'Manish',
'email': '[email protected]',
'role': 'Student',
};
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return UserScreen(
userData: userData,
);
},
),
);
Receive the Map:
class UserScreen extends StatelessWidget {
final Map<String, String> userData;
const UserScreen({
super.key,
required this.userData,
});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Text(userData['name'] ?? ''),
Text(userData['email'] ?? ''),
Text(userData['role'] ?? ''),
],
),
);
}
}
For larger applications with well-defined data structures, model classes are often easier to maintain than loosely structured maps.
14. Sending Information Using RouteSettings
Flutter also allows information to be attached to a route using RouteSettings.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const ProductDetailsScreen();
},
settings: RouteSettings(
arguments: product,
),
),
);
The destination screen can retrieve the information from the current route.
class ProductDetailsScreen extends StatelessWidget {
const ProductDetailsScreen({super.key});
@override
Widget build(BuildContext context) {
final product =
ModalRoute.of(context)!.settings.arguments as Product;
return Scaffold(
appBar: AppBar(
title: Text(product.name),
),
body: Center(
child: Text(
'Price: ₹${product.price}',
),
),
);
}
}
Flutter's official cookbook documents this approach using RouteSettings(arguments: ...) and retrieving the object through ModalRoute.of(context). :contentReference[oaicite:1]{index=1}
15. Sending Information Using Named Routes
Flutter supports passing arguments through named routes.
Navigator.pushNamed(
context,
'/product',
arguments: product,
);
The destination screen can retrieve the argument:
class ProductScreen extends StatelessWidget {
const ProductScreen({super.key});
@override
Widget build(BuildContext context) {
final product =
ModalRoute.of(context)!.settings.arguments as Product;
return Scaffold(
appBar: AppBar(
title: Text(product.name),
),
body: Center(
child: Text(
'₹${product.price}',
),
),
);
}
}
Flutter's documentation notes that named routes are not recommended for most new applications. For many applications, Flutter recommends using Navigator with MaterialPageRoute or a routing package such as go_router. :contentReference[oaicite:2]{index=2}
16. Passing Multiple Arguments With a Custom Class
When several values need to be passed through a named route, creating a dedicated arguments class can make the data easier to organize.
class ScreenArguments {
final String title;
final String message;
final int userId;
const ScreenArguments({
required this.title,
required this.message,
required this.userId,
});
}
Create the arguments:
final arguments = ScreenArguments(
title: 'Profile',
message: 'Welcome to your profile',
userId: 1001,
);
Pass them to the route:
Navigator.pushNamed(
context,
'/profile',
arguments: arguments,
);
Extract them from the destination:
final args =
ModalRoute.of(context)!.settings.arguments
as ScreenArguments;
Text(args.title);
Text(args.message);
Text('User ID: ${args.userId}');
The official Flutter named-route cookbook uses a similar arguments-class pattern for transferring multiple values. :contentReference[oaicite:3]{index=3}
17. Receiving Data Back From Another Screen
Information can also travel in the opposite direction. A second screen can return a result to the first screen using Navigator.pop().
Second Screen
class SelectionScreen extends StatelessWidget {
const SelectionScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Select Course'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(
context,
'Flutter Course Selected',
);
},
child: const Text('Select Flutter'),
),
),
);
}
}
First Screen
Future<void> selectCourse(BuildContext context) async {
final result = await Navigator.push<String>(
context,
MaterialPageRoute(
builder: (context) {
return const SelectionScreen();
},
),
);
if (result != null) {
print('Result: $result');
}
}
Flutter's official documentation demonstrates returning information from a pushed screen by passing a result to Navigator.pop() and awaiting the result from Navigator.push(). Flutter: Return data from a screen
18. Sending Data and Receiving Updated Data
A common application flow is:
Screen A
|
| Send existing data
v
Screen B
|
| Modify data
v
Screen A
|
| Receive updated data
User Model
class User {
final String name;
final String email;
const User({
required this.name,
required this.email,
});
}
Open Edit Screen
final updatedUser = await Navigator.push<User>(
context,
MaterialPageRoute(
builder: (context) {
return EditUserScreen(
user: user,
);
},
),
);
if (updatedUser != null) {
print(updatedUser.name);
print(updatedUser.email);
}
Edit Screen
class EditUserScreen extends StatelessWidget {
final User user;
const EditUserScreen({
super.key,
required this.user,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Edit User'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
final updatedUser = User(
name: 'Updated User',
email: user.email,
);
Navigator.pop(
context,
updatedUser,
);
},
child: const Text('Save'),
),
),
);
}
}
19. Passing Data From Parent Screen to Child Screen
Screen-to-screen communication often follows the same principles as normal widget communication. Data can be passed to the child widget through constructor parameters.
class DetailsScreen extends StatelessWidget {
final String title;
final String description;
const DetailsScreen({
super.key,
required this.title,
required this.description,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Text(description),
),
);
}
}
This approach keeps the destination screen independent because the required information is explicitly provided to it.
20. Practical Example: Student List to Student Details
Student Model
class Student {
final int id;
final String name;
final String course;
final int age;
const Student({
required this.id,
required this.name,
required this.course,
required this.age,
});
}
Student List
class StudentListScreen extends StatelessWidget {
StudentListScreen({super.key});
final students = const [
Student(
id: 1,
name: 'Rahul',
course: 'Flutter',
age: 22,
),
Student(
id: 2,
name: 'Priya',
course: 'Dart',
age: 21,
),
Student(
id: 3,
name: 'Amit',
course: 'UI/UX',
age: 24,
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Students'),
),
body: ListView.builder(
itemCount: students.length,
itemBuilder: (context, index) {
final student = students[index];
return ListTile(
leading: CircleAvatar(
child: Text('${student.id}'),
),
title: Text(student.name),
subtitle: Text(student.course),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return StudentDetailsScreen(
student: student,
);
},
),
);
},
);
},
),
);
}
}
Student Details
class StudentDetailsScreen extends StatelessWidget {
final Student student;
const StudentDetailsScreen({
super.key,
required this.student,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(student.name),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
student.name,
style: const TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
Text('Student ID: ${student.id}'),
Text('Age: ${student.age}'),
Text('Course: ${student.course}'),
],
),
),
);
}
}
21. Complete Application Example
The following example demonstrates a complete flow where a product is selected from one screen, sent to a details screen, and a result is returned.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class Product {
final int id;
final String name;
final double price;
const Product({
required this.id,
required this.name,
required this.price,
});
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Screen Data Example',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
),
useMaterial3: true,
),
home: const ProductListScreen(),
);
}
}
class ProductListScreen extends StatelessWidget {
const ProductListScreen({super.key});
static const products = [
Product(
id: 1,
name: 'Flutter Course',
price: 4999,
),
Product(
id: 2,
name: 'Dart Course',
price: 3999,
),
Product(
id: 3,
name: 'UI/UX Course',
price: 2999,
),
];
Future<void> openProduct(
BuildContext context,
Product product,
) async {
final result = await Navigator.push<String>(
context,
MaterialPageRoute(
builder: (context) {
return ProductDetailsScreen(
product: product,
);
},
),
);
if (result != null && context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(result),
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Products'),
),
body: ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
final product = products[index];
return ListTile(
title: Text(product.name),
subtitle: Text(
'₹${product.price.toStringAsFixed(0)}',
),
trailing: const Icon(
Icons.arrow_forward_ios,
),
onTap: () {
openProduct(
context,
product,
);
},
);
},
),
);
}
}
class ProductDetailsScreen extends StatelessWidget {
final Product product;
const ProductDetailsScreen({
super.key,
required this.product,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(product.name),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
product.name,
style: Theme.of(context)
.textTheme
.headlineSmall,
),
const SizedBox(height: 10),
Text(
'Product ID: ${product.id}',
),
const SizedBox(height: 8),
Text(
'Price: ₹${product.price.toStringAsFixed(0)}',
),
const Spacer(),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
Navigator.pop(
context,
'${product.name} selected successfully',
);
},
child: const Text('Select Product'),
),
),
],
),
),
);
}
}
Application Flow
- The Product List screen contains product objects.
- The user selects a product.
Navigator.push() opens the Product Details screen.
- The selected Product object is passed through the constructor.
- The Product Details screen displays the product information.
- The user taps the Select Product button.
Navigator.pop() sends a result back.
- The first screen receives the result using
await Navigator.push().
- A
SnackBar displays the returned message.
22. Using go_router for Passing Information
For applications with more complex navigation requirements, Flutter documentation recommends considering Router-based navigation or a routing package such as go_router. Flutter's documentation describes go_router as a package maintained by the Flutter team for complex routing scenarios. :contentReference[oaicite:4]{index=4}
A simplified example of passing an object with go_router is:
context.push(
'/product-details',
extra: product,
);
The destination route can access the extra value:
GoRoute(
path: '/product-details',
builder: (context, state) {
final product = state.extra as Product;
return ProductDetailsScreen(
product: product,
);
},
)
For applications requiring advanced deep linking, web URL synchronization, or complex navigation structures, Router-based navigation can provide a more structured solution. :contentReference[oaicite:5]{index=5}
23. Difference Between Passing Data and Shared State
Requirement |
Possible Approach |
|---|
Send one value to the next screen |
Constructor parameter |
Send a complete model object |
Constructor parameter |
Pass route arguments |
RouteSettings |
Use named route arguments |
pushNamed() with arguments |
Return a value to the previous screen |
Navigator.pop() |
Share changing data across many unrelated widgets |
State-management solution |
Handle complex navigation and deep links |
Router or routing package |
24. Common Mistakes
Mistake 1: Forgetting to Pass Required Data
class DetailsScreen extends StatelessWidget {
final String name;
const DetailsScreen({
super.key,
required this.name,
});
}
When opening this screen, the required name value must be supplied.
Mistake 2: Using the Wrong Data Type
class ProductScreen extends StatelessWidget {
final int productId;
const ProductScreen({
super.key,
required this.productId,
});
}
The destination expects an int, so the calling code should provide an integer.
Mistake 3: Unsafe Route Argument Casting
final product =
ModalRoute.of(context)!.settings.arguments as Product;
When using dynamically passed route arguments, make sure the expected object is actually supplied to the route.
Mistake 4: Passing Too Many Independent Parameters
If a screen requires many related values, consider creating a model class instead of passing many individual parameters.
Mistake 5: Using Global Variables for Simple Navigation
Global variables can make data flow harder to understand. For simple screen-to-screen communication, direct constructor parameters are often easier to trace.
25. Best Practices
- Use constructor parameters for simple and strongly typed screen-to-screen data.
- Create model classes for structured information.
- Use
required parameters when the destination cannot work without the data.
- Use typed navigation results such as
Navigator.push<String>() when expecting a return value.
- Use
Navigator.pop(context, result) to send information back.
- Keep model classes separate from UI code as applications become larger.
- Validate dynamically supplied route arguments.
- Avoid using global variables for simple data transfer.
- Use state-management solutions when application data must be shared across multiple unrelated widgets.
- For advanced navigation and deep linking, consider Router-based navigation or a routing package.
26. Constructor vs RouteSettings vs Named Route Arguments
Feature |
Constructor |
RouteSettings |
Named Route Arguments |
|---|
Simple to understand |
Yes |
Moderate |
Moderate |
Strongly typed at the widget API |
Yes |
No |
No |
Can pass custom objects |
Yes |
Yes |
Yes |
Works with Navigator.push() |
Yes |
Yes |
No |
Works with pushNamed() |
No |
Can be used by route creation |
Yes |
Useful for simple screen data |
Yes |
Yes |
Available but has limitations |
27. Interview Questions
Q1. How can you send information from one screen to another in Flutter?
You can pass information through constructor parameters, route arguments, named-route arguments, or a routing solution depending on the application's navigation architecture.
Q2. How do you pass an object between screens?
Create a Dart model object and pass it to the destination screen through a constructor or another supported route-argument mechanism.
Q3. How can a screen return information to the previous screen?
Use Navigator.pop(context, result) on the current screen and await the result from the previous screen.
Q4. What is RouteSettings?
RouteSettings stores route-related information and can contain an arguments object for transferring information to a route.
Q5. What is the difference between Navigator.push() and Navigator.pop()?
Navigator.push() adds a new route to the navigation stack, while Navigator.pop() removes the current route and can optionally return a result.
Q6. Can a list be sent between screens?
Yes. A Dart List can be passed through a constructor or another route-argument mechanism.
Q7. When should you use a model class?
A model class is useful when the information contains multiple related properties, such as a product, student, user, order, or course.
28. Practice Exercises
- Create a login screen and send the username to the Home Screen.
- Create a product list and send the selected product to a Product Details screen.
- Create a student list and send the selected student object to a Student Details screen.
- Create a registration form and send the submitted information to a Confirmation screen.
- Create a shopping cart and send a list of products to the Checkout screen.
- Create a category list and send the selected category ID to the Product List screen.
- Create an Edit Profile screen that receives a User object and returns an updated User object.
- Create a course-selection screen that returns the selected course name to the previous screen.
29. Quick Revision
Concept |
Syntax |
|---|
Open another screen |
Navigator.push() |
Send constructor data |
Screen(value: data) |
Send route argument |
RouteSettings(arguments: data) |
Send named-route argument |
Navigator.pushNamed(..., arguments: data) |
Read route argument |
ModalRoute.of(context)!.settings.arguments |
Return information |
Navigator.pop(context, result) |
Receive returned information |
await Navigator.push<T>(...) |
30. Key Takeaways
- Flutter screens and pages are represented by routes.
- The
Navigator manages the route stack.
- Constructor parameters provide a straightforward way to send strongly typed information.
- Custom Dart objects can be passed between screens.
RouteSettings can be used to attach arguments to a route.
- Named routes support arguments, although Flutter does not recommend them for most new applications.
Navigator.pop() can return information to the previous screen.
- Typed navigation results make returned data easier to work with.
- State management is useful when information must be shared and updated across multiple unrelated parts of an application.
- Router-based navigation or packages such as
go_router can be used for advanced navigation and deep-linking requirements.
31. Official Flutter Documentation
32. Flutter Training Resources