4
4
5
5
import 'package:flutter/material.dart' ;
6
6
7
- bool _isLargeScreen (BuildContext context) {
8
- return MediaQuery .of (context).size.width > 960.0 ;
9
- }
7
+ typedef NavigationType NavigationTypeResolver (BuildContext context);
10
8
11
- bool _isMediumScreen (BuildContext context) {
12
- return MediaQuery .of (context).size.width > 640.0 ;
9
+ // The type of navigation to configure to.
10
+ enum NavigationType {
11
+ bottomNavigation,
12
+ navigationRail,
13
+ drawer,
13
14
}
14
15
15
16
/// See bottomNavigationBarItem or NavigationRailDestination
@@ -34,6 +35,7 @@ class AdaptiveNavigationScaffold extends StatefulWidget {
34
35
final List <AdaptiveScaffoldDestination > destinations;
35
36
final ValueChanged <int > onNavigationIndexChange;
36
37
final FloatingActionButton floatingActionButton;
38
+ final NavigationTypeResolver navigationTypeResolver;
37
39
38
40
AdaptiveNavigationScaffold ({
39
41
this .title,
@@ -42,6 +44,7 @@ class AdaptiveNavigationScaffold extends StatefulWidget {
42
44
@required this .destinations,
43
45
this .onNavigationIndexChange,
44
46
this .floatingActionButton,
47
+ this .navigationTypeResolver,
45
48
}) : assert (currentIndex != null ),
46
49
assert (destinations != null );
47
50
@@ -52,105 +55,120 @@ class AdaptiveNavigationScaffold extends StatefulWidget {
52
55
53
56
class _AdaptiveNavigationScaffoldState
54
57
extends State <AdaptiveNavigationScaffold > {
58
+ NavigationType _defaultNavigationTypeResolver (BuildContext context) {
59
+ if (_isLargeScreen (context)) {
60
+ return NavigationType .drawer;
61
+ } else if (_isMediumScreen (context)) {
62
+ return NavigationType .navigationRail;
63
+ } else {
64
+ return NavigationType .bottomNavigation;
65
+ }
66
+ }
67
+
55
68
@override
56
69
Widget build (BuildContext context) {
57
- // Show a Drawer
58
- if (_isLargeScreen (context)) {
59
- return Row (
60
- children: [
61
- Drawer (
62
- child: Column (
63
- children: [
64
- DrawerHeader (
65
- child: Center (
66
- child: widget.title,
67
- ),
70
+ final NavigationTypeResolver navigationTypeResolver =
71
+ widget.navigationTypeResolver ?? _defaultNavigationTypeResolver;
72
+ switch (navigationTypeResolver (context)) {
73
+ case NavigationType .bottomNavigation:
74
+ // Show a Scaffold with a BottomNavigationBar.
75
+ return Scaffold (
76
+ body: widget.body,
77
+ appBar: AppBar (title: widget.title),
78
+ bottomNavigationBar: BottomNavigationBar (
79
+ items: [
80
+ for (final destination in widget.destinations)
81
+ BottomNavigationBarItem (
82
+ icon: Icon (destination.icon),
83
+ title: Text (destination.title),
68
84
),
69
- for (var d in widget.destinations)
70
- ListTile (
71
- leading: Icon (d.icon),
72
- title: Text (d.title),
73
- selected:
74
- widget.destinations.indexOf (d) == widget.currentIndex,
75
- onTap: () => _destinationTapped (d),
76
- ),
77
- ],
78
- ),
85
+ ],
86
+ currentIndex: widget.currentIndex,
87
+ onTap: widget.onNavigationIndexChange,
79
88
),
80
- VerticalDivider (
81
- width: 1 ,
82
- thickness: 1 ,
83
- color: Colors .grey[300 ],
89
+ floatingActionButton: widget.floatingActionButton,
90
+ );
91
+ case NavigationType .navigationRail:
92
+ // Show a Scaffold with a body containing a NavigationRail.
93
+ return Scaffold (
94
+ appBar: AppBar (
95
+ title: widget.title,
84
96
),
85
- Expanded (
86
- child: Scaffold (
87
- appBar: AppBar (),
88
- body: widget.body,
89
- floatingActionButton: widget.floatingActionButton,
90
- ),
97
+ body: Row (
98
+ children: [
99
+ NavigationRail (
100
+ leading: widget.floatingActionButton,
101
+ destinations: [
102
+ for (final destination in widget.destinations)
103
+ NavigationRailDestination (
104
+ icon: Icon (destination.icon),
105
+ label: Text (destination.title),
106
+ ),
107
+ ],
108
+ selectedIndex: widget.currentIndex,
109
+ onDestinationSelected: widget.onNavigationIndexChange ?? (_) {},
110
+ ),
111
+ VerticalDivider (
112
+ width: 1 ,
113
+ thickness: 1 ,
114
+ ),
115
+ Expanded (
116
+ child: widget.body,
117
+ ),
118
+ ],
91
119
),
92
- ],
93
- );
94
- }
95
-
96
- // Show a navigation rail
97
- if (_isMediumScreen (context)) {
98
- return Scaffold (
99
- appBar: AppBar (
100
- title: widget.title,
101
- ),
102
- body: Row (
120
+ );
121
+ case NavigationType .drawer:
122
+ // Show a Row containing a Drawer and Scaffold.
123
+ return Row (
103
124
children: [
104
- NavigationRail (
105
- leading : widget.floatingActionButton,
106
- destinations : [
107
- ...widget.destinations. map (
108
- (d) => NavigationRailDestination (
109
- icon : Icon (d.icon) ,
110
- label : Text (d.title ),
125
+ Drawer (
126
+ child : Column (
127
+ children : [
128
+ DrawerHeader (
129
+ child : Center (
130
+ child : widget.title ,
131
+ ),
111
132
),
112
- ),
113
- ],
114
- selectedIndex: widget.currentIndex,
115
- onDestinationSelected: widget.onNavigationIndexChange ?? (_) {},
133
+ for (final destination in widget.destinations)
134
+ ListTile (
135
+ leading: Icon (destination.icon),
136
+ title: Text (destination.title),
137
+ selected: widget.destinations.indexOf (destination) ==
138
+ widget.currentIndex,
139
+ onTap: () => _destinationTapped (destination),
140
+ ),
141
+ ],
142
+ ),
116
143
),
117
144
VerticalDivider (
118
145
width: 1 ,
119
146
thickness: 1 ,
120
- color: Colors .grey[300 ],
121
147
),
122
148
Expanded (
123
- child: widget.body,
149
+ child: Scaffold (
150
+ appBar: AppBar (),
151
+ body: widget.body,
152
+ floatingActionButton: widget.floatingActionButton,
153
+ ),
124
154
),
125
155
],
126
- ),
127
- );
156
+ );
128
157
}
129
-
130
- // Show a bottom app bar
131
- return Scaffold (
132
- body: widget.body,
133
- appBar: AppBar (title: widget.title),
134
- bottomNavigationBar: BottomNavigationBar (
135
- items: [
136
- ...widget.destinations.map (
137
- (d) => BottomNavigationBarItem (
138
- icon: Icon (d.icon),
139
- title: Text (d.title),
140
- ),
141
- ),
142
- ],
143
- currentIndex: widget.currentIndex,
144
- onTap: widget.onNavigationIndexChange,
145
- ),
146
- floatingActionButton: widget.floatingActionButton,
147
- );
148
158
}
149
159
150
160
void _destinationTapped (AdaptiveScaffoldDestination destination) {
151
- var idx = widget.destinations.indexOf (destination);
152
- if (idx != widget.currentIndex) {
153
- widget.onNavigationIndexChange (idx );
161
+ final index = widget.destinations.indexOf (destination);
162
+ if (index != widget.currentIndex) {
163
+ widget.onNavigationIndexChange (index );
154
164
}
155
165
}
156
166
}
167
+
168
+ bool _isLargeScreen (BuildContext context) {
169
+ return MediaQuery .of (context).size.width > 960.0 ;
170
+ }
171
+
172
+ bool _isMediumScreen (BuildContext context) {
173
+ return MediaQuery .of (context).size.width > 640.0 ;
174
+ }
0 commit comments