Created
March 20, 2025 15:23
-
-
Save prof3ssorSt3v3/8c663fea5ea965c90143a970d0f1f843 to your computer and use it in GitHub Desktop.
Example of Nested Navigation in Flutter with named routes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
/// Flutter code sample for [Navigator]. | |
void main() => runApp(const NavigatorExampleApp()); | |
class NavigatorExampleApp extends StatelessWidget { | |
const NavigatorExampleApp({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
// MaterialApp contains our top-level Navigator | |
initialRoute: '/', | |
routes: <String, WidgetBuilder>{ | |
'/': (BuildContext context) => const HomePage(), | |
'/signup': (BuildContext context) => const SignUpPage(), | |
}, | |
); | |
} | |
} | |
class HomePage extends StatelessWidget { | |
const HomePage({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return DefaultTextStyle( | |
style: Theme.of(context).textTheme.headlineMedium!, | |
child: Container( | |
color: Colors.white, | |
alignment: Alignment.center, | |
child: const Text('Home Page'), | |
), | |
); | |
} | |
} | |
class CollectPersonalInfoPage extends StatelessWidget { | |
const CollectPersonalInfoPage({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return DefaultTextStyle( | |
style: Theme.of(context).textTheme.headlineMedium!, | |
child: GestureDetector( | |
onTap: () { | |
// This moves from the personal info page to the credentials page, | |
// replacing this page with that one. | |
Navigator.of(context).pushReplacementNamed('signup/choose_credentials'); | |
}, | |
child: Container( | |
color: Colors.lightBlue, | |
alignment: Alignment.center, | |
child: const Text('Collect Personal Info Page'), | |
), | |
), | |
); | |
} | |
} | |
class ChooseCredentialsPage extends StatelessWidget { | |
const ChooseCredentialsPage({super.key, required this.onSignupComplete}); | |
final VoidCallback onSignupComplete; | |
@override | |
Widget build(BuildContext context) { | |
return GestureDetector( | |
onTap: onSignupComplete, | |
child: DefaultTextStyle( | |
style: Theme.of(context).textTheme.headlineMedium!, | |
child: Container( | |
color: Colors.pinkAccent, | |
alignment: Alignment.center, | |
child: const Text('Choose Credentials Page'), | |
), | |
), | |
); | |
} | |
} | |
class SignUpPage extends StatelessWidget { | |
const SignUpPage({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
// SignUpPage builds its own Navigator which ends up being a nested | |
// Navigator in our app. | |
return Navigator( | |
initialRoute: 'signup/personal_info', | |
onGenerateRoute: (RouteSettings settings) { | |
WidgetBuilder builder; | |
switch (settings.name) { | |
case 'signup/personal_info': | |
// Assume CollectPersonalInfoPage collects personal info and then | |
// navigates to 'signup/choose_credentials'. | |
builder = (BuildContext context) => const CollectPersonalInfoPage(); | |
case 'signup/choose_credentials': | |
// Assume ChooseCredentialsPage collects new credentials and then | |
// invokes 'onSignupComplete()'. | |
builder = | |
(BuildContext _) => ChooseCredentialsPage( | |
onSignupComplete: () { | |
// Referencing Navigator.of(context) from here refers to the | |
// top level Navigator because SignUpPage is above the | |
// nested Navigator that it created. Therefore, this pop() | |
// will pop the entire "sign up" journey and return to the | |
// "/" route, AKA HomePage. | |
Navigator.of(context).pop(); | |
}, | |
); | |
default: | |
throw Exception('Invalid route: ${settings.name}'); | |
} | |
return MaterialPageRoute<void>(builder: builder, settings: settings); | |
}, | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment