Jonny Borges
Committed by GitHub

Merge pull request #375 from Nipodemos/code_docs

[docs] Documenting main methods
1 import 'package:flutter/widgets.dart'; 1 import 'package:flutter/widgets.dart';
2 2
3 extension MDQ on BuildContext { 3 extension MDQ on BuildContext {
  4 + /// The same of [MediaQuery.of(context).size]
4 Size get mediaQuerySize => MediaQuery.of(this).size; 5 Size get mediaQuerySize => MediaQuery.of(this).size;
5 6
  7 + /// The same of [MediaQuery.of(context).size.height]
  8 + /// Note: updates when you rezise your screen (like on a browser or desktop window)
6 double get height => mediaQuerySize.height; 9 double get height => mediaQuerySize.height;
7 10
  11 + /// The same of [MediaQuery.of(context).size.width]
  12 + /// Note: updates when you rezise your screen (like on a browser or desktop window)
8 double get width => mediaQuerySize.width; 13 double get width => mediaQuerySize.width;
9 14
  15 + /// Gives you the power to get a portion of the height.
  16 + /// Useful for responsive applications.
  17 + ///
  18 + /// [dividedBy] is for when you want to have a portion of the value you would get
  19 + /// like for example: if you want a value that represents a third of the screen
  20 + /// you can set it to 3, and you will get a third of the height
  21 + ///
  22 + /// [reducedBy] is a percentage value of how much of the height you want
  23 + /// if you for example want 46% of the height, then you reduce it by 56%.
10 double heightTransformer({double dividedBy = 1, double reducedBy = 0.0}) { 24 double heightTransformer({double dividedBy = 1, double reducedBy = 0.0}) {
11 return (mediaQuerySize.height - 25 return (mediaQuerySize.height -
12 ((mediaQuerySize.height / 100) * reducedBy)) / 26 ((mediaQuerySize.height / 100) * reducedBy)) /
13 dividedBy; 27 dividedBy;
14 } 28 }
15 29
  30 + /// Gives you the power to get a portion of the width.
  31 + /// Useful for responsive applications.
  32 + ///
  33 + /// [dividedBy] is for when you want to have a portion of the value you would get
  34 + /// like for example: if you want a value that represents a third of the screen
  35 + /// you can set it to 3, and you will get a third of the width
  36 + ///
  37 + /// [reducedBy] is a percentage value of how much of the width you want
  38 + /// if you for example want 46% of the width, then you reduce it by 56%.
16 double widthTransformer({double dividedBy = 1, double reducedBy = 0.0}) { 39 double widthTransformer({double dividedBy = 1, double reducedBy = 0.0}) {
17 return (mediaQuerySize.width - ((mediaQuerySize.width / 100) * reducedBy)) / 40 return (mediaQuerySize.width - ((mediaQuerySize.width / 100) * reducedBy)) /
18 dividedBy; 41 dividedBy;
19 } 42 }
20 43
21 - double ratio(  
22 - {double dividedBy = 1,  
23 - double reducedByW = 0.0,  
24 - double reducedByH = 0.0}) { 44 + /// TODO: make docs about that
  45 + double ratio({
  46 + double dividedBy = 1,
  47 + double reducedByW = 0.0,
  48 + double reducedByH = 0.0,
  49 + }) {
25 return heightTransformer(dividedBy: dividedBy, reducedBy: reducedByH) / 50 return heightTransformer(dividedBy: dividedBy, reducedBy: reducedByH) /
26 widthTransformer(dividedBy: dividedBy, reducedBy: reducedByW); 51 widthTransformer(dividedBy: dividedBy, reducedBy: reducedByW);
27 } 52 }
28 53
29 - /// similar to MediaQuery.of(this).padding 54 + /// similar to [MediaQuery.of(context).padding]
30 EdgeInsets get mediaQueryPadding => MediaQuery.of(this).padding; 55 EdgeInsets get mediaQueryPadding => MediaQuery.of(this).padding;
31 56
32 - /// similar to MediaQuery.of(this).viewPadding 57 + /// similar to [MediaQuery.of(context).viewPadding]
33 EdgeInsets get mediaQueryViewPadding => MediaQuery.of(this).viewPadding; 58 EdgeInsets get mediaQueryViewPadding => MediaQuery.of(this).viewPadding;
34 59
35 - /// similar to MediaQuery.of(this).viewInsets; 60 + /// similar to [MediaQuery.of(context).viewInsets]
36 EdgeInsets get mediaQueryViewInsets => MediaQuery.of(this).viewInsets; 61 EdgeInsets get mediaQueryViewInsets => MediaQuery.of(this).viewInsets;
37 62
38 - /// similar to MediaQuery.of(this).orientation; 63 + /// similar to [MediaQuery.of(context).orientation]
39 Orientation get orientation => MediaQuery.of(this).orientation; 64 Orientation get orientation => MediaQuery.of(this).orientation;
40 65
41 /// check if device is on landscape mode 66 /// check if device is on landscape mode
@@ -44,10 +69,10 @@ extension MDQ on BuildContext { @@ -44,10 +69,10 @@ extension MDQ on BuildContext {
44 /// check if device is on portrait mode 69 /// check if device is on portrait mode
45 bool get isPortrait => orientation == Orientation.portrait; 70 bool get isPortrait => orientation == Orientation.portrait;
46 71
47 - /// similar to MediaQuery.of(this).devicePixelRatio; 72 + /// similar to [MediaQuery.of(this).devicePixelRatio]
48 double get devicePixelRatio => MediaQuery.of(this).devicePixelRatio; 73 double get devicePixelRatio => MediaQuery.of(this).devicePixelRatio;
49 74
50 - /// similar to MediaQuery.of(this).textScaleFactor; 75 + /// similar to [MediaQuery.of(this).textScaleFactor]
51 double get textScaleFactor => MediaQuery.of(this).textScaleFactor; 76 double get textScaleFactor => MediaQuery.of(this).textScaleFactor;
52 77
53 /// get the shortestSide from screen 78 /// get the shortestSide from screen
@@ -29,56 +29,107 @@ class GetImpl implements GetService { @@ -29,56 +29,107 @@ class GetImpl implements GetService {
29 RouteSettings settings; 29 RouteSettings settings;
30 String defaultSeparator = "_"; 30 String defaultSeparator = "_";
31 31
32 - ///Use to instead of Navigator.push, off instead of Navigator.pushReplacement,  
33 - ///offAll instead of Navigator.pushAndRemoveUntil. For named routes just add "named"  
34 - ///after them. Example: toNamed, offNamed, and AllNamed.  
35 - ///To return to the previous screen, use back().  
36 - ///No need to pass any context to Get, just put the name of the route inside  
37 - ///the parentheses and the magic will occur.  
38 -  
39 - /// It replaces Navigator.push, but needs no context, and it doesn't have the Navigator.push  
40 - /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior  
41 - /// of rebuilding every app after a route, use opaque = true as the parameter.  
42 - Future<T> to<T>(Widget page,  
43 - {bool opaque,  
44 - Transition transition,  
45 - Duration duration,  
46 - int id,  
47 - bool fullscreenDialog = false,  
48 - Object arguments,  
49 - Bindings binding,  
50 - preventDuplicates = true,  
51 - bool popGesture}) { 32 + /// Pushes a new [page] to the stack
  33 + ///
  34 + /// It has the advantage of not needing context,
  35 + /// so you can call from your business logic
  36 + ///
  37 + /// You can set a custom [transition], and a transition [duration].
  38 + ///
  39 + /// You can send any type of value to the other route in the [arguments].
  40 + ///
  41 + /// Just like native routing in Flutter, you can push a route
  42 + /// as a [fullscreenDialog],
  43 + ///
  44 + /// [id] is for when you are using nested navigation,
  45 + /// as explained in documentation
  46 + ///
  47 + /// If you want the same behavior of ios that pops a route when the user drag,
  48 + /// you can set [popGesture] to true
  49 + ///
  50 + /// If you're using the [Bindings] api, you must define it here
  51 + ///
  52 + /// By default, GetX will prevent you from push a route that you already in,
  53 + /// if you want to push anyway, set [preventDuplicates] to false
  54 + Future<T> to<T>(
  55 + Widget page, {
  56 + bool opaque,
  57 + Transition transition,
  58 + Duration duration,
  59 + int id,
  60 + bool fullscreenDialog = false,
  61 + Object arguments,
  62 + Bindings binding,
  63 + preventDuplicates = true,
  64 + bool popGesture,
  65 + }) {
52 if (preventDuplicates && '/${page.runtimeType}' == currentRoute) { 66 if (preventDuplicates && '/${page.runtimeType}' == currentRoute) {
53 return null; 67 return null;
54 } 68 }
55 69
56 - return global(id).currentState.push(GetPageRoute(  
57 - opaque: opaque ?? true,  
58 - page: () => page,  
59 - settings:  
60 - RouteSettings(name: '/${page.runtimeType}', arguments: arguments),  
61 - popGesture: popGesture ?? defaultPopGesture,  
62 - transition: transition ?? defaultTransition,  
63 - fullscreenDialog: fullscreenDialog,  
64 - binding: binding,  
65 - transitionDuration: duration ?? defaultDurationTransition));  
66 - }  
67 -  
68 - /// It replaces Navigator.pushNamed, but needs no context, and it doesn't have the Navigator.pushNamed  
69 - /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior  
70 - /// of rebuilding every app after a route, use opaque = true as the parameter.  
71 - Future<T> toNamed<T>(String page,  
72 - {Object arguments, int id, preventDuplicates = true}) { 70 + return global(id).currentState.push(
  71 + GetPageRoute(
  72 + opaque: opaque ?? true,
  73 + page: () => page,
  74 + settings: RouteSettings(
  75 + name: '/${page.runtimeType}',
  76 + arguments: arguments,
  77 + ),
  78 + popGesture: popGesture ?? defaultPopGesture,
  79 + transition: transition ?? defaultTransition,
  80 + fullscreenDialog: fullscreenDialog,
  81 + binding: binding,
  82 + transitionDuration: duration ?? defaultDurationTransition,
  83 + ),
  84 + );
  85 + }
  86 +
  87 + /// Pushes a new named [page] to the stack
  88 + ///
  89 + /// It has the advantage of not needing context, so you can call
  90 + /// from your business logic.
  91 + ///
  92 + /// You can send any type of value to the other route in the [arguments].
  93 + ///
  94 + /// [id] is for when you are using nested navigation,
  95 + /// as explained in documentation
  96 + ///
  97 + /// By default, GetX will prevent you from push a route that you already in,
  98 + /// if you want to push anyway, set [preventDuplicates] to false
  99 + ///
  100 + /// Note: Always put a slash on the route ('/page1'), to avoid unnexpected errors
  101 + Future<T> toNamed<T>(
  102 + String page, {
  103 + Object arguments,
  104 + int id,
  105 + preventDuplicates = true,
  106 + }) {
73 if (preventDuplicates && page == currentRoute) { 107 if (preventDuplicates && page == currentRoute) {
74 return null; 108 return null;
75 } 109 }
76 return global(id).currentState.pushNamed(page, arguments: arguments); 110 return global(id).currentState.pushNamed(page, arguments: arguments);
77 } 111 }
78 112
79 - /// It replaces Navigator.pushReplacementNamed, but needs no context.  
80 - Future<T> offNamed<T>(String page,  
81 - {Object arguments, int id, preventDuplicates = true}) { 113 + /// Pop the current named [page] in the stack and push a new one in its place
  114 + ///
  115 + /// It has the advantage of not needing context, so you can call
  116 + /// from your business logic.
  117 + ///
  118 + /// You can send any type of value to the other route in the [arguments].
  119 + ///
  120 + /// [id] is for when you are using nested navigation,
  121 + /// as explained in documentation
  122 + ///
  123 + /// By default, GetX will prevent you from push a route that you already in,
  124 + /// if you want to push anyway, set [preventDuplicates] to false
  125 + ///
  126 + /// Note: Always put a slash on the route ('/page1'), to avoid unnexpected errors
  127 + Future<T> offNamed<T>(
  128 + String page, {
  129 + Object arguments,
  130 + int id,
  131 + preventDuplicates = true,
  132 + }) {
82 if (preventDuplicates && page == currentRoute) { 133 if (preventDuplicates && page == currentRoute) {
83 return null; 134 return null;
84 } 135 }
@@ -87,29 +138,72 @@ class GetImpl implements GetService { @@ -87,29 +138,72 @@ class GetImpl implements GetService {
87 .pushReplacementNamed(page, arguments: arguments); 138 .pushReplacementNamed(page, arguments: arguments);
88 } 139 }
89 140
90 - /// It replaces Navigator.popUntil, but needs no context. 141 + /// Calls pop several times in the stack until [predicate] returns true
  142 + ///
  143 + /// [id] is for when you are using nested navigation,
  144 + /// as explained in documentation
  145 + ///
  146 + /// [predicate] can be used like this:
  147 + /// `Get.until(Get.currentRoute == '/home')`so when you get to home page,
  148 + ///
  149 + /// or also like this:
  150 + /// `Get.until(!Get.isDialogOpen())`, to make sure the dialog is closed
91 void until(RoutePredicate predicate, {int id}) { 151 void until(RoutePredicate predicate, {int id}) {
92 // if (key.currentState.mounted) // add this if appear problems on future with route navigate 152 // if (key.currentState.mounted) // add this if appear problems on future with route navigate
93 // when widget don't mounted 153 // when widget don't mounted
94 return global(id).currentState.popUntil(predicate); 154 return global(id).currentState.popUntil(predicate);
95 } 155 }
96 156
97 - /// It replaces Navigator.pushAndRemoveUntil, but needs no context. 157 + /// Push the given [page], and then pop several [pages] in the stack until
  158 + /// [predicate] returns true
  159 + ///
  160 + /// [id] is for when you are using nested navigation,
  161 + /// as explained in documentation
  162 + ///
  163 + /// [predicate] can be used like this:
  164 + /// `Get.until(Get.currentRoute == '/home')`so when you get to home page,
  165 + ///
  166 + /// or also like this:
  167 + /// `Get.until(!Get.isDialogOpen())`, to make sure the dialog is closed
98 Future<T> offUntil<T>(Route<T> page, RoutePredicate predicate, {int id}) { 168 Future<T> offUntil<T>(Route<T> page, RoutePredicate predicate, {int id}) {
99 // if (key.currentState.mounted) // add this if appear problems on future with route navigate 169 // if (key.currentState.mounted) // add this if appear problems on future with route navigate
100 // when widget don't mounted 170 // when widget don't mounted
101 return global(id).currentState.pushAndRemoveUntil(page, predicate); 171 return global(id).currentState.pushAndRemoveUntil(page, predicate);
102 } 172 }
103 173
104 - /// It replaces Navigator.pushNamedAndRemoveUntil, but needs no context.  
105 - Future<T> offNamedUntil<T>(String page, RoutePredicate predicate,  
106 - {int id, Object arguments}) { 174 + /// Push the given named [page], and then pop several pages in the stack
  175 + /// until [predicate] returns true
  176 + ///
  177 + /// You can send any type of value to the other route in the [arguments].
  178 + ///
  179 + /// [id] is for when you are using nested navigation,
  180 + /// as explained in documentation
  181 + ///
  182 + /// [predicate] can be used like this:
  183 + /// `Get.until(Get.currentRoute == '/home')`so when you get to home page,
  184 + /// or also like
  185 + /// `Get.until(!Get.isDialogOpen())`, to make sure the dialog is closed
  186 + ///
  187 + /// Note: Always put a slash on the route ('/page1'), to avoid unnexpected errors
  188 + Future<T> offNamedUntil<T>(
  189 + String page,
  190 + RoutePredicate predicate, {
  191 + int id,
  192 + Object arguments,
  193 + }) {
107 return global(id) 194 return global(id)
108 .currentState 195 .currentState
109 .pushNamedAndRemoveUntil(page, predicate, arguments: arguments); 196 .pushNamedAndRemoveUntil(page, predicate, arguments: arguments);
110 } 197 }
111 198
112 - /// It replaces Navigator.popAndPushNamed, but needs no context. 199 + /// Pop the current named page and pushes a new [page] to the stack in its place
  200 + ///
  201 + /// You can send any type of value to the other route in the [arguments].
  202 + /// It is very similar to `offNamed()` but use a different approach
  203 + ///
  204 + /// The `offNamed()` pop a page, and goes to the next. The `offAndToNamed()` goes
  205 + /// to the next page, and removes the previous one. The route transition
  206 + /// animation is different.
113 Future<T> offAndToNamed<T>(String page, 207 Future<T> offAndToNamed<T>(String page,
114 {Object arguments, int id, dynamic result}) { 208 {Object arguments, int id, dynamic result}) {
115 return global(id) 209 return global(id)
@@ -117,12 +211,25 @@ class GetImpl implements GetService { @@ -117,12 +211,25 @@ class GetImpl implements GetService {
117 .popAndPushNamed(page, arguments: arguments, result: result); 211 .popAndPushNamed(page, arguments: arguments, result: result);
118 } 212 }
119 213
120 - /// It replaces Navigator.removeRoute, but needs no context. 214 + /// Remove a specific [route] from the stack
  215 + ///
  216 + /// [id] is for when you are using nested navigation,
  217 + /// as explained in documentation
121 void removeRoute(Route<dynamic> route, {int id}) { 218 void removeRoute(Route<dynamic> route, {int id}) {
122 return global(id).currentState.removeRoute(route); 219 return global(id).currentState.removeRoute(route);
123 } 220 }
124 221
125 - /// It replaces Navigator.pushNamedAndRemoveUntil, but needs no context. 222 + /// Push a named [page] and remove all other pages from stack
  223 + ///
  224 + /// It has the advantage of not needing context, so you can
  225 + /// call from your business logic.
  226 + ///
  227 + /// You can send any type of value to the other route in the [arguments].
  228 + ///
  229 + /// [id] is for when you are using nested navigation,
  230 + /// as explained in documentation
  231 + ///
  232 + /// Note: Always put a slash on the route ('/page1'), to avoid unexpected errors
126 Future<T> offAllNamed<T>(String newRouteName, 233 Future<T> offAllNamed<T>(String newRouteName,
127 {RoutePredicate predicate, Object arguments, int id}) { 234 {RoutePredicate predicate, Object arguments, int id}) {
128 var route = (Route<dynamic> rota) => false; 235 var route = (Route<dynamic> rota) => false;
@@ -132,18 +239,30 @@ class GetImpl implements GetService { @@ -132,18 +239,30 @@ class GetImpl implements GetService {
132 arguments: arguments); 239 arguments: arguments);
133 } 240 }
134 241
  242 + /// Returns true if a snackbar, dialog or bottomsheet is currently showing in the screen
135 bool get isOverlaysOpen => 243 bool get isOverlaysOpen =>
136 (isSnackbarOpen || isDialogOpen || isBottomSheetOpen); 244 (isSnackbarOpen || isDialogOpen || isBottomSheetOpen);
137 245
  246 + /// returns true if there is no snackbar, dialog or bottomsheet open
138 bool get isOverlaysClosed => 247 bool get isOverlaysClosed =>
139 (!isSnackbarOpen && !isDialogOpen && !isBottomSheetOpen); 248 (!isSnackbarOpen && !isDialogOpen && !isBottomSheetOpen);
140 249
141 - /// It replaces Navigator.pop, but needs no context.  
142 - void back(  
143 - {dynamic result,  
144 - bool closeOverlays = false,  
145 - bool canPop = true,  
146 - int id}) { 250 + /// Pop the current page, snackbar, dialog or bottomsheet in the stack
  251 + ///
  252 + /// if your set [closeOverlays] to true, Get.back() will close the currently open
  253 + /// snackbar/dialog/bottomsheet AND the current page
  254 + ///
  255 + /// [id] is for when you are using nested navigation,
  256 + /// as explained in documentation
  257 + ///
  258 + /// It has the advantage of not needing context, so you can call
  259 + /// from your business logic.
  260 + void back({
  261 + dynamic result,
  262 + bool closeOverlays = false,
  263 + bool canPop = true,
  264 + int id,
  265 + }) {
147 if (closeOverlays && isOverlaysOpen) { 266 if (closeOverlays && isOverlaysOpen) {
148 navigator.popUntil((route) { 267 navigator.popUntil((route) {
149 return (isOverlaysClosed); 268 return (isOverlaysClosed);
@@ -158,7 +277,7 @@ class GetImpl implements GetService { @@ -158,7 +277,7 @@ class GetImpl implements GetService {
158 } 277 }
159 } 278 }
160 279
161 - /// It will close as many screens as you define. Times must be> 0; 280 + /// Close as many routes as defined by [times]
162 void close(int times, [int id]) { 281 void close(int times, [int id]) {
163 if ((times == null) || (times < 1)) { 282 if ((times == null) || (times < 1)) {
164 times = 1; 283 times = 1;
@@ -170,19 +289,40 @@ class GetImpl implements GetService { @@ -170,19 +289,40 @@ class GetImpl implements GetService {
170 return back; 289 return back;
171 } 290 }
172 291
173 - /// It replaces Navigator.pushReplacement, but needs no context, and it doesn't have the Navigator.pushReplacement  
174 - /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior  
175 - /// of rebuilding every app after a route, use opaque = true as the parameter.  
176 - Future<T> off<T>(Widget page,  
177 - {bool opaque = false,  
178 - Transition transition,  
179 - bool popGesture,  
180 - int id,  
181 - Object arguments,  
182 - Bindings binding,  
183 - bool fullscreenDialog = false,  
184 - preventDuplicates = true,  
185 - Duration duration}) { 292 + /// Pop the current page and pushes a new [page] to the stack
  293 + ///
  294 + /// It has the advantage of not needing context,
  295 + /// so you can call from your business logic
  296 + ///
  297 + /// You can set a custom [transition], and a transition [duration].
  298 + ///
  299 + /// You can send any type of value to the other route in the [arguments].
  300 + ///
  301 + /// Just like native routing in Flutter, you can push a route
  302 + /// as a [fullscreenDialog],
  303 + ///
  304 + /// [id] is for when you are using nested navigation,
  305 + /// as explained in documentation
  306 + ///
  307 + /// If you want the same behavior of ios that pops a route when the user drag,
  308 + /// you can set [popGesture] to true
  309 + ///
  310 + /// If you're using the [Bindings] api, you must define it here
  311 + ///
  312 + /// By default, GetX will prevent you from push a route that you already in,
  313 + /// if you want to push anyway, set [preventDuplicates] to false
  314 + Future<T> off<T>(
  315 + Widget page, {
  316 + bool opaque = false,
  317 + Transition transition,
  318 + bool popGesture,
  319 + int id,
  320 + Object arguments,
  321 + Bindings binding,
  322 + bool fullscreenDialog = false,
  323 + preventDuplicates = true,
  324 + Duration duration,
  325 + }) {
186 if (preventDuplicates && '/${page.runtimeType}' == currentRoute) { 326 if (preventDuplicates && '/${page.runtimeType}' == currentRoute) {
187 return null; 327 return null;
188 } 328 }
@@ -198,17 +338,45 @@ class GetImpl implements GetService { @@ -198,17 +338,45 @@ class GetImpl implements GetService {
198 transitionDuration: duration ?? defaultDurationTransition)); 338 transitionDuration: duration ?? defaultDurationTransition));
199 } 339 }
200 340
201 - /// It replaces Navigator.pushAndRemoveUntil, but needs no context  
202 - Future<T> offAll<T>(Widget page,  
203 - {RoutePredicate predicate,  
204 - bool opaque = false,  
205 - bool popGesture,  
206 - int id,  
207 - Object arguments,  
208 - Bindings binding,  
209 - bool fullscreenDialog = false,  
210 - Duration duration,  
211 - Transition transition}) { 341 + /// Pop all pages in the stack and pushes a new [page] to it
  342 + ///
  343 + /// It has the advantage of not needing context,
  344 + /// so you can call from your business logic
  345 + ///
  346 + /// You can set a custom [transition], and a transition [duration].
  347 + ///
  348 + /// You can send any type of value to the other route in the [arguments].
  349 + ///
  350 + /// Just like native routing in Flutter, you can push a route
  351 + /// as a [fullscreenDialog],
  352 + ///
  353 + /// [predicate] can be used like this:
  354 + /// `Get.until(Get.currentRoute == '/home')`so when you get to home page,
  355 + /// or also like
  356 + /// `Get.until(!Get.isDialogOpen())`, to make sure the dialog is closed
  357 + ///
  358 + /// [id] is for when you are using nested navigation,
  359 + /// as explained in documentation
  360 + ///
  361 + /// If you want the same behavior of ios that pops a route when the user drag,
  362 + /// you can set [popGesture] to true
  363 + ///
  364 + /// If you're using the [Bindings] api, you must define it here
  365 + ///
  366 + /// By default, GetX will prevent you from push a route that you already in,
  367 + /// if you want to push anyway, set [preventDuplicates] to false
  368 + Future<T> offAll<T>(
  369 + Widget page, {
  370 + RoutePredicate predicate,
  371 + bool opaque = false,
  372 + bool popGesture,
  373 + int id,
  374 + Object arguments,
  375 + Bindings binding,
  376 + bool fullscreenDialog = false,
  377 + Duration duration,
  378 + Transition transition,
  379 + }) {
212 var route = (Route<dynamic> rota) => false; 380 var route = (Route<dynamic> rota) => false;
213 381
214 return global(id).currentState.pushAndRemoveUntil( 382 return global(id).currentState.pushAndRemoveUntil(