// Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 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); }, ); } }