Using Named Routes
1. Defining Named Routes
| Property | Description | Example |
|---|---|---|
| name | Name of the route | 'home' |
| builder | Function that builds the widget for this route | (context) => HomeScreen() |
Example: Defining a Named Route
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => HomeScreen(),
'/profile': (context) => ProfileScreen(),
},
),
);
}
2. Navigating with Named Routes
| Property | Description | Example |
|---|---|---|
| onGenerateRoute | Callback to generate routes dynamically | onGenerateRoute: (settings) { ... } |
| onUnknownRoute | Handler for undefined routes | onUnknownRoute: (settings) { ... } |
Example: Defining Named Routes
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => HomeScreen(),
'/profile': (context) => ProfileScreen(),
'/settings': (context) => SettingsScreen(),
},
);
}
}
Example: Passing Arguments to Named Routes
Navigator.pushNamed(
context,
'/user',
arguments: {'id': '123', 'name': 'John'},
);
Note: Named routes must be defined in the
routes map of MaterialApp or WidgetsApp.
Warning: Using
Navigator.pushNamed without defining the route will throw an exception.
3. Using onGenerateRoute Callback
| Property | Description | Usage |
|---|---|---|
| onGenerateRoute | Callback function to handle route generation for named routes not defined in routes |
|
Example: onGenerateRoute Implementation
MaterialApp(
onGenerateRoute: (RouteSettings settings) {
if (settings.name == '/user') {
return MaterialPageRoute(
builder: (context) => UserScreen(),
settings: settings,
);
}
return null; // Route not found
},
)
Note:
onGenerateRoute is called when a route is not found in the routes map.
Key Points
onGenerateRouteis used for dynamic route generation.- It's called when a named route is not found in the
routesmap. - Returns a
Routeobject ornullif route is not handled.
4. Using onUnknownRoute Callback
| Property | Description | Usage |
|---|---|---|
| onUnknownRoute | Callback invoked when a route is not found in the route table. | onUnknownRoute: (RouteSettings settings) { ... } |
Example: Handling Unknown Routes
MaterialApp(
onUnknownRoute: (RouteSettings settings) {
return MaterialPageRoute(
builder: (context) => Scaffold(
appBar: AppBar(title: Text('Route Not Found')),
body: Center(child: Text('The route \${settings.name} was not found.')),
),
);
},
)
Note: The
onUnknownRoute is useful for displaying a custom 404 page or redirecting to a default route when a user navigates to an invalid route.5. Passing Arguments to Named Routes
| Argument Type | Description | Usage |
|---|---|---|
| arguments | Passes a single argument to the route | Navigator.pushNamed(context, '/route', arguments: {'key': 'value'}); |
| arguments | Passes multiple arguments to the route | Navigator.pushNamed(context, '/route', arguments: {'name': 'John', 'age': 30}); |
Example: Accessing Arguments in Route
class MyRoutePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>;
return Scaffold(
appBar: AppBar(title: Text('Arguments Page')),
body: Center(
child: Text('Name: ${args['name']}, Age: ${args['age']}'),
),
);
}
}
6. Extracting Route Arguments
| Property | Description | Example |
|---|---|---|
| ModalRoute.of(context) | Retrieves the current route from the navigation stack | |
| settings.arguments | Arguments passed to the route during navigation | |
Example: Extracting Route Arguments
class UserScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final route = ModalRoute.of(context);
final String? id = route?.settings.arguments['id'];
return Scaffold(
appBar: AppBar(title: Text('User $id')),
body: Center(child: Text('User ID: $id')),
);
}
}
7. Using RouteSettings Class
| Property | Description | Example |
|---|---|---|
| name | The route name (optional) | '/user/profile' |
| arguments | Arguments passed to the route (optional) | {'userId': '123'} |
| isInitialRoute | Indicates if this is the initial route (read-only) | false |
Example: Creating a Route with RouteSettings
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => HomeScreen(),
'/user/profile': (context) => UserProfileScreen(),
},
onGenerateRoute: (settings) {
if (settings.name == '/user/profile') {
return MaterialPageRoute(
builder: (context) => UserProfileScreen(),
settings: RouteSettings(
name: '/user/profile',
arguments: {'userId': '123'},
),
);
}
return null;
},
);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Home')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pushNamed(
context,
'/user/profile',
arguments: {'userId': '123'},
);
},
child: Text('Go to Profile'),
),
),
);
}
}
class UserProfileScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as Map?;
return Scaffold(
appBar: AppBar(title: Text('User Profile')),
body: Center(
child: Text('User ID: ${args?['userId']}'),
),
);
}
}
8. Creating Route Observers
Route observers allow you to monitor route changes and lifecycle events in your Flutter app. They are useful for logging, analytics, or performing actions when specific routes are pushed or popped.
| Property | Description | Usage |
|---|---|---|
| didPush | Called when a new route is pushed onto the stack. | void didPush(Route route, Route previousRoute) |
| didPop | Called when a route is popped from the stack. | void didPop(Route route, Route previousRoute) |
| didRemove | Called when a route is removed from the stack. | void didRemove(Route route, Route previousRoute) |
| didPushNext | Called when a new route is pushed on top of the current route. | void didPushNext(Route route, Route previousRoute) |
| didPopNext | Called when the current route is popped and replaced with another. | void didPopNext(Route route, Route previousRoute) |
Example: Implementing Route Observer
class MyRouteObserver extends RouteObserver<PageRoute> {
@override
void didPush(Route route, Route previousRoute) {
print('New route pushed: ${route.settings.name}');
}
@override
void didPop(Route route, Route previousRoute) {
print('Route popped: ${route.settings.name}');
}
}
Example: Using Route Observer in App
void main() {
runApp(
MaterialApp(
navigatorObservers: [MyRouteObserver()],
home: HomeScreen(),
),
);
}
9. Implementing Route Guards
Route guards in Flutter are used to control access to routes based on conditions such as authentication status, user permissions, or other business logic. They help in preventing unauthorized navigation to specific screens.
| Guard Type | Description | Implementation |
|---|---|---|
| Navigation Guard | Prevents navigation to a route based on conditions. | |
| Redirect Guard | Redirects to another route if the current route is not accessible. | |
Example: Navigation Guard Implementation
class AuthGuard {
static Route<Object>? onGenerateRoute(RouteSettings settings) {
if (settings.name == '/dashboard') {
if (!isAuthenticated) {
return MaterialPageRoute(
builder: (context) => LoginScreen(),
);
}
}
return null;
}
}
Note: Route guards are typically implemented using
onGenerateRoute in the MaterialApp or WidgetsApp widget.
Warning: Ensure that all guards are properly handled to avoid infinite loops or unexpected behavior during navigation.
10. Using initialRoute Property
| Property | Description | Usage |
|---|---|---|
| initialRoute | Specifies the route to navigate to when the app starts. | initialRoute: '/home' |
Example: Setting initialRoute in MaterialApp
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/home',
routes: {
'/home': (context) => HomeScreen(),
'/profile': (context) => ProfileScreen(),
},
);
}
}