Skip to content

Commit 84bc4b4

Browse files
committed
Support Nested Navigator Back Button
1 parent 7aaf098 commit 84bc4b4

File tree

6 files changed

+143
-45
lines changed

6 files changed

+143
-45
lines changed

lib/pages/authorization/authorization_navigation.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:developer' as developer;
22
import 'package:cubit_app_flow/pages/authorization/sign_in/sign_in_page.dart';
3+
import 'package:cubit_app_flow/utils/navigator/navigator_support.dart';
34
import 'package:flutter/material.dart';
45

56
class AuthorizationNavigation extends StatefulWidget {
@@ -12,7 +13,7 @@ class _AuthorizationNavigationState extends State<AuthorizationNavigation> {
1213
static const TAG = 'AuthorizationNavigation';
1314
@override
1415
Widget build(BuildContext context) {
15-
return Navigator(
16+
return NavigatorSupport(
1617
initialRoute: SignInPage.ROUTE_NAME,
1718
onGenerateRoute: (settings) {
1819
switch(settings.name) {

lib/pages/authorized/authorized_navigation.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:developer' as developer;
22
import 'package:cubit_app_flow/pages/authorized/home/home_page.dart';
33
import 'package:cubit_app_flow/pages/authorized/profile/profile_edit_page.dart';
4+
import 'package:cubit_app_flow/utils/navigator/navigator_support.dart';
45
import 'package:flutter/material.dart';
56

67
import 'module1/module1_navigation.dart';
@@ -16,7 +17,7 @@ class _AuthorizedNavigationState extends State<AuthorizedNavigation> {
1617
GlobalKey<NavigatorState> navigationKey = GlobalKey(debugLabel: 'AuthorizedNavigation');
1718
@override
1819
Widget build(BuildContext context) {
19-
return Navigator(
20+
return NavigatorSupport(
2021
key: navigationKey,
2122
initialRoute: HomePage.ROUTE_NAME,
2223
onGenerateRoute: (settings) {
@@ -28,7 +29,7 @@ class _AuthorizedNavigationState extends State<AuthorizedNavigation> {
2829
);
2930
case Module1Navigation.ROUTE_NAME:
3031
return MaterialPageRoute(
31-
builder: (context) => Module1Navigation(navigationKey),
32+
builder: (context) => Module1Navigation(),
3233
settings: settings
3334
);
3435
default:

lib/pages/authorized/module1/module1_navigation.dart

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import 'dart:developer' as developer;
22
import 'package:cubit_app_flow/pages/authorized/module1/root_module1_page.dart';
3+
import 'package:cubit_app_flow/utils/navigator/navigator_support.dart';
34
import 'package:flutter/material.dart';
45

56
class Module1Navigation extends StatefulWidget {
67
static const ROUTE_NAME = 'Module1Navigation';
7-
final GlobalKey<NavigatorState> parentNavigation;
8-
9-
Module1Navigation(this.parentNavigation);
108

119
@override
1210
_Module1NavigationState createState() => _Module1NavigationState();
@@ -16,17 +14,13 @@ class _Module1NavigationState extends State<Module1Navigation> {
1614
static const TAG = 'Module1Navigation';
1715
@override
1816
Widget build(BuildContext context) {
19-
return Navigator(
17+
return NavigatorSupport(
2018
initialRoute: RootModule1Page.ROUTE_NAME,
2119
onGenerateRoute: (settings) {
2220
switch(settings.name) {
2321
default:
2422
return MaterialPageRoute(
25-
builder: (context) => RootModule1Page(
26-
() {
27-
widget.parentNavigation.currentState?.pop();
28-
}
29-
),
23+
builder: (context) => RootModule1Page(),
3024
);
3125
}
3226
},

lib/pages/authorized/module1/root_module1_page.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import 'dart:developer' as developer;
2+
import 'package:cubit_app_flow/utils/navigator/navigator_support.dart';
23
import 'package:flutter/material.dart';
34

45
class RootModule1Page extends StatefulWidget {
56
static const ROUTE_NAME = 'RootModule1Page';
6-
final VoidCallback onBackRoot;
7-
8-
RootModule1Page(this.onBackRoot);
7+
RootModule1Page();
98

109
@override
1110
_RootModule1PageState createState() => _RootModule1PageState();
@@ -18,7 +17,9 @@ class _RootModule1PageState extends State<RootModule1Page> {
1817
return Scaffold(
1918
appBar: AppBar(
2019
leading: BackButton(
21-
onPressed: widget.onBackRoot,
20+
onPressed: () {
21+
NavigatorSupport.of(context).parent.pop();
22+
},
2223
),
2324
title: Text('Root Module1 Page'),
2425
),
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import 'package:flutter/material.dart';
2+
3+
/// Support Nested Navigation Back Android
4+
class NavigatorSupport extends StatefulWidget {
5+
static const ROUTE_NAME = 'NavigatorSupport';
6+
7+
final List<Page<dynamic>> pages;
8+
final PopPageCallback onPopPage;
9+
final String initialRoute;
10+
final RouteFactory onGenerateRoute;
11+
final RouteFactory onUnknownRoute;
12+
final List<NavigatorObserver> observers;
13+
static const String defaultRouteName = '/';
14+
final RouteListFactory onGenerateInitialRoutes;
15+
final TransitionDelegate<dynamic> transitionDelegate;
16+
17+
NavigatorSupport({
18+
Key key,
19+
this.pages = const <Page<dynamic>>[],
20+
this.onPopPage,
21+
this.initialRoute,
22+
this.onGenerateInitialRoutes = Navigator.defaultGenerateInitialRoutes,
23+
this.onGenerateRoute,
24+
this.onUnknownRoute,
25+
this.transitionDelegate = const DefaultTransitionDelegate<dynamic>(),
26+
this.observers = const <NavigatorObserver>[],
27+
}): super(key: key);
28+
29+
@override
30+
NavigatorSupportState createState() => NavigatorSupportState();
31+
32+
static NavigatorSupportState of(
33+
BuildContext context) {
34+
// Handles the case where the input context is a navigator element.
35+
NavigatorSupportState navigator;
36+
if (context is StatefulElement && context.state is NavigatorSupportState) {
37+
navigator = context.state as NavigatorSupportState;
38+
}
39+
navigator = navigator ?? context.findAncestorStateOfType<NavigatorSupportState>();
40+
return navigator;
41+
}
42+
43+
}
44+
45+
class NavigatorSupportState extends State<NavigatorSupport> {
46+
static const TAG = 'NavigatorSupport';
47+
GlobalKey<NavigatorState> navigatorKey = GlobalKey();
48+
49+
NavigatorState _parentNavigator;
50+
51+
NavigatorState get parent => _parentNavigator;
52+
53+
@override
54+
void didChangeDependencies() {
55+
super.didChangeDependencies();
56+
if (_parentNavigator != Navigator.of(context)) {
57+
_parentNavigator = Navigator.of(context);
58+
}
59+
}
60+
61+
@override
62+
Widget build(BuildContext context) {
63+
return WillPopScope(
64+
child: Navigator(
65+
pages: widget.pages,
66+
key: navigatorKey,
67+
onGenerateRoute: widget.onGenerateRoute,
68+
initialRoute: widget.initialRoute,
69+
transitionDelegate: widget.transitionDelegate,
70+
observers: [],
71+
onGenerateInitialRoutes: widget.onGenerateInitialRoutes,
72+
onPopPage: widget.onPopPage,
73+
onUnknownRoute: widget.onUnknownRoute,
74+
),
75+
onWillPop: () async {
76+
if (navigatorKey.currentState.canPop()) {
77+
navigatorKey.currentState.pop();
78+
return false;
79+
} else {
80+
return true;
81+
}
82+
},
83+
);
84+
}
85+
}
86+
87+

0 commit comments

Comments
 (0)