Implementing Basic Navigation
1. Using Navigator.push() Method
| Property | Description | Example |
|---|---|---|
| context | The BuildContext of the current widget | BuildContext context |
| widget | The widget to navigate to | Widget widget |
Example: Pushing a New Screen
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(),
),
);
MaterialPageRoute is used for iOS and Android platforms.
context is valid and accessible within the scope where Navigator is called.
2. Using Navigator.pop() Method
| Method | Description | Parameters | Return Type |
|---|---|---|---|
| Navigator.pop() | Removes the current screen from the navigation stack and returns to the previous screen. | BuildContext context |
Future<bool> |
| Navigator.pop(context, result) | Removes the current screen and returns a result to the previous screen. | BuildContext context, Object? result |
Future<bool> |
Example: Navigating Back with Result
class MyScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('My Screen')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, 'Result from MyScreen');
},
child: Text('Go Back with Result'),
),
),
);
}
}
Example: Navigating Back Without Result
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second Screen')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go Back'),
),
),
);
}
}
Navigator.pop() method is asynchronous and returns a Future. It's important to await it if you're performing actions after navigation.
3. Using MaterialPageRoute Widget
| Property | Values | Description |
|---|---|---|
| builder | WidgetBuilder |
Required. A function that builds the widget for the new screen. |
| fullscreenDialog | bool |
Optional. If true, the route is a full-screen dialog. |
| maintainState | bool |
Optional. If false, the route's widget is disposed when popped. |
| pageStorageBucket | PageStorageBucket |
Optional. The bucket to use for page storage. |
| transitionDelegate | TransitionDelegate |
Optional. Controls how the route transitions. |
| reverseTransitionDelegate | TransitionDelegate |
Optional. Controls how the route transitions when popped. |
Example: Navigating to a New Screen
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(),
),
);
}
Example: Passing Data to the New Screen
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(
title: 'Second Screen',
),
),
);
}
MaterialPageRoute is the default route for Material Design apps in Flutter.
4. Using CupertinoPageRoute Widget
| Property | Values | Description |
|---|---|---|
| builder | WidgetBuilder |
Required. The widget builder for the route content. |
| fullscreenDialog | bool |
Optional. Whether the route is a full-screen dialog. |
| maintainState | bool |
Optional. Whether to keep the route's state when it is not visible. |
| name | String |
Optional. The name of the route for debugging purposes. |
| settings | RouteSettings |
Optional. Additional settings for the route. |
Example: Navigating with CupertinoPageRoute
import 'package:flutter/cupertino.dart';
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Home'),
),
child: Center(
child: CupertinoButton(
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => SecondScreen(),
),
);
},
child: Text('Go to Second Screen'),
),
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Second Screen'),
),
child: Center(
child: Text('This is the second screen.'),
),
);
}
}
5. Passing Arguments to Routes
| Property | Description | Example |
|---|---|---|
| arguments | Passes a map of arguments to the route | {'userId': '123', 'userName': 'JohnDoe'} |
| onGenerateRoute | Used to define custom route handling logic | |
Example: Passing Arguments to a Route
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserProfileScreen(
arguments: {'userId': '123'},
),
),
);
Example: Accessing Passed Arguments
class UserProfileScreen extends StatelessWidget {
final Map<String, dynamic> arguments;
UserProfileScreen({required this.arguments});
@override
Widget build(BuildContext context) {
final userId = arguments['userId'];
return Scaffold(
appBar: AppBar(title: Text('User Profile')),
body: Center(child: Text('User ID: $userId')),
);
}
}
6. Receiving Data from Popped Routes
| Property | Description | Usage |
|---|---|---|
| result | Value returned when popping a route | Navigator.pop(context, result); |
Example: Receiving Data from Popped Route
class DataReceiver extends StatefulWidget {
@override
_DataReceiverState createState() => _DataReceiverState();
}
class _DataReceiverState extends State<DataReceiver> {
String receivedData = "";
Future<void> _navigateAndReceiveData() async {
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DataSender(),
),
);
if (result != null) {
setState(() {
receivedData = result;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Data Receiver")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Received: $receivedData"),
ElevatedButton(
onPressed: _navigateAndReceiveData,
child: Text("Navigate to Sender"),
),
],
),
),
);
}
}
Example: Sending Data from Route
class DataSender extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Data Sender")),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, "Hello from sender!");
},
child: Text("Send Data and Pop"),
),
),
);
}
}
7. Using Navigator.pushReplacement() Method
The Navigator.pushReplacement() method in Flutter is used to navigate to a new screen and replace the current screen in the navigation stack. This means that when the user presses the back button, they will not return to the previous screen but instead exit the app or navigate to a different screen.
| Parameter | Description | Required |
|---|---|---|
| context | The BuildContext of the current screen. | Yes |
| page | The new screen (Widget) to navigate to. | Yes |
Example: Using Navigator.pushReplacement()
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(),
),
);
pushReplacement method replaces the current screen in the stack, so it's useful for login flows or when you want to prevent users from returning to a previous screen.
8. Using Navigator.pushAndRemoveUntil() Method
The Navigator.pushAndRemoveUntil() method is used to navigate to a new screen and remove all previous screens from the stack until a certain condition is met. This is useful for scenarios like logging out and returning to the login screen.
| Parameter | Type | Description |
|---|---|---|
| context | BuildContext |
The build context of the current screen. |
| predicate | RoutePredicate |
A function that determines which routes to keep in the stack. |
| route | Route |
The new route to navigate to. |
Example: Navigating to a Home Screen and Removing All Previous Screens
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => HomeScreen()),
(route) => route.isFirst,
);
isFirst property is used to identify the first route in the stack, ensuring all previous routes are removed.
9. Using Navigator.popUntil() Method
The Navigator.popUntil() method is used to pop multiple screens from the navigation stack until a specific condition is met. It allows you to navigate back to a particular screen in the stack, rather than popping one screen at a time.
| Parameter | Type | Description |
|---|---|---|
| navigator | NavigatorState |
The navigator state instance to use for popping screens. |
| predicate | bool Function(Route<Object> route) |
A function that determines whether to pop the current route. Returns true if the route should be popped. |
Example: Pop until a specific route is reached
Navigator.popUntil(
context,
(route) => route.settings.name == '/home',
);
popUntil method is useful for navigating back to a specific screen in the stack, such as returning to the home screen after completing a multi-step process.10. Handling Back Button
| Property | Description | Usage |
|---|---|---|
| onBackPressed | Callback function when the back button is pressed | onBackPressed: () { ... } |
| canPop | Indicates if the current route can be popped | bool canPop = Navigator.canPop(context); |
Example: Handling Back Button in Flutter
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Home")),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
},
child: Text("Go to Second Page"),
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Page"),
leading: BackButton(
onPressed: () {
// Custom back button behavior
Navigator.of(context).pop();
},
),
),
body: Center(
child: Text("This is the second page"),
),
);
}
}
BackButton widget can be customized to handle back button presses with custom logic.
onPressed callback in BackButton properly navigates or handles the back press to avoid unexpected behavior.