| // Copyright 2013 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. |
| |
| // ignore_for_file: public_member_api_docs |
| |
| import 'package:flutter/material.dart'; |
| import 'package:go_router/go_router.dart'; |
| |
| part 'shell_route_with_keys_example.g.dart'; |
| |
| void main() => runApp(App()); |
| |
| final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>(); |
| final GlobalKey<NavigatorState> shellNavigatorKey = GlobalKey<NavigatorState>(); |
| |
| class App extends StatelessWidget { |
| App({super.key}); |
| |
| @override |
| Widget build(BuildContext context) => MaterialApp.router( |
| routerConfig: _router, |
| ); |
| |
| final GoRouter _router = GoRouter( |
| routes: $appRoutes, |
| initialLocation: '/home', |
| navigatorKey: rootNavigatorKey, |
| ); |
| } |
| |
| @TypedShellRoute<MyShellRouteData>( |
| routes: <TypedRoute<RouteData>>[ |
| TypedGoRoute<HomeRouteData>(path: '/home'), |
| TypedGoRoute<UsersRouteData>( |
| path: '/users', |
| routes: <TypedGoRoute<UserRouteData>>[ |
| TypedGoRoute<UserRouteData>(path: ':id'), |
| ], |
| ), |
| ], |
| ) |
| class MyShellRouteData extends ShellRouteData { |
| const MyShellRouteData(); |
| |
| static final GlobalKey<NavigatorState> $navigatorKey = shellNavigatorKey; |
| |
| @override |
| Widget builder(BuildContext context, GoRouterState state, Widget navigator) { |
| return MyShellRouteScreen(child: navigator); |
| } |
| } |
| |
| class MyShellRouteScreen extends StatelessWidget { |
| const MyShellRouteScreen({required this.child, super.key}); |
| |
| final Widget child; |
| |
| int getCurrentIndex(BuildContext context) { |
| final String location = GoRouterState.of(context).location; |
| if (location.startsWith('/users')) { |
| return 1; |
| } |
| return 0; |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| final int selectedIndex = getCurrentIndex(context); |
| |
| return Scaffold( |
| body: Row( |
| children: <Widget>[ |
| NavigationRail( |
| destinations: const <NavigationRailDestination>[ |
| NavigationRailDestination( |
| icon: Icon(Icons.home), |
| label: Text('Home'), |
| ), |
| NavigationRailDestination( |
| icon: Icon(Icons.group), |
| label: Text('Users'), |
| ), |
| ], |
| selectedIndex: selectedIndex, |
| onDestinationSelected: (int index) { |
| switch (index) { |
| case 0: |
| const HomeRouteData().go(context); |
| break; |
| case 1: |
| const UsersRouteData().go(context); |
| break; |
| } |
| }, |
| ), |
| const VerticalDivider(thickness: 1, width: 1), |
| Expanded(child: child), |
| ], |
| ), |
| ); |
| } |
| } |
| |
| class HomeRouteData extends GoRouteData { |
| const HomeRouteData(); |
| |
| @override |
| Widget build(BuildContext context, GoRouterState state) { |
| return const Center(child: Text('The home page')); |
| } |
| } |
| |
| class UsersRouteData extends GoRouteData { |
| const UsersRouteData(); |
| |
| @override |
| Widget build(BuildContext context, GoRouterState state) { |
| return ListView( |
| children: <Widget>[ |
| for (int userID = 1; userID <= 3; userID++) |
| ListTile( |
| title: Text('User $userID'), |
| onTap: () => UserRouteData(id: userID).go(context), |
| ), |
| ], |
| ); |
| } |
| } |
| |
| class DialogPage extends Page<void> { |
| /// A page to display a dialog. |
| const DialogPage({required this.child, super.key}); |
| |
| /// The widget to be displayed which is usually a [Dialog] widget. |
| final Widget child; |
| |
| @override |
| Route<void> createRoute(BuildContext context) { |
| return DialogRoute<void>( |
| context: context, |
| settings: this, |
| builder: (BuildContext context) => child, |
| ); |
| } |
| } |
| |
| class UserRouteData extends GoRouteData { |
| const UserRouteData({required this.id}); |
| |
| // Without this static key, the dialog will not cover the navigation rail. |
| static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey; |
| |
| final int id; |
| |
| @override |
| Page<void> buildPage(BuildContext context, GoRouterState state) { |
| return DialogPage( |
| key: state.pageKey, |
| child: Center( |
| child: SizedBox( |
| width: 300, |
| height: 300, |
| child: Card(child: Center(child: Text('User $id'))), |
| ), |
| ), |
| ); |
| } |
| } |