Showing
10 changed files
with
594 additions
and
156 deletions
1 | +## [2.2.2] | ||
2 | +- Fix GetRoute not found | ||
3 | + | ||
4 | +## [2.2.1] | ||
5 | +- Improve lazyPut | ||
6 | + | ||
7 | +## [2.2.0] | ||
8 | +- Added: Ability to choose or delay a widget's state change according to its ID. | ||
9 | +- Added: Ability to fire triggers when loading materialApp. | ||
10 | +- Added: Ability to change theme dynamically. | ||
11 | +- Added: Ability to rebuild the entire app with one command. | ||
12 | +- Added: Ability to trigger events on the MaterialApp. | ||
13 | +- Added: Get.lazyPut (lazy loading of dependencies). | ||
14 | +- Added: Get.creator - a factory of dependencies . | ||
15 | +- Added: Capability of define abstract class on dependencies. | ||
16 | + | ||
17 | +## [2.1.2] | ||
18 | +- Get.defaultDialog refactor | ||
19 | + | ||
20 | +## [2.1.1] | ||
21 | +- fix typo | ||
22 | + | ||
23 | +## [2.1.0] | ||
24 | +- Added Get.rawSnackbar | ||
25 | +- Added instantInit config to snackbars | ||
26 | +- Refactor Get Instance Manager | ||
27 | +- Improved performance and bug fix to Get State Manager | ||
28 | +- Improved performance of GetRoute on namedRoutes | ||
29 | +- Hotfix on namedRoutes | ||
30 | + | ||
1 | ## [2.0.10] | 31 | ## [2.0.10] |
2 | - Bump new Flutter version | 32 | - Bump new Flutter version |
3 | - Added Get.generalDialog | 33 | - Added Get.generalDialog |
1 | # Get | 1 | # Get |
2 | 2 | ||
3 | Get is an extra-light and powerful library for Flutter that will give you superpowers and increase your productivity. Navigate without context, open dialogs, snackbars or bottomsheets from anywhere in your code, Manage states and inject dependencies in an easy and practical way! Get is secure, stable, up-to-date, and offers a huge range of APIs that are not present on default framework. | 3 | Get is an extra-light and powerful library for Flutter that will give you superpowers and increase your productivity. Navigate without context, open dialogs, snackbars or bottomsheets from anywhere in your code, Manage states and inject dependencies in an easy and practical way! Get is secure, stable, up-to-date, and offers a huge range of APIs that are not present on default framework. |
4 | + | ||
4 | ```dart | 5 | ```dart |
5 | // Default Flutter navigator | 6 | // Default Flutter navigator |
6 | Navigator.of(context).push( | 7 | Navigator.of(context).push( |
7 | context, | 8 | context, |
8 | MaterialPageRoute( | 9 | MaterialPageRoute( |
9 | builder: (BuildContext context) { | 10 | builder: (BuildContext context) { |
10 | - return HomePage(); | 11 | + return Home(); |
11 | }, | 12 | }, |
12 | ), | 13 | ), |
13 | ); | 14 | ); |
@@ -196,16 +197,8 @@ To open default dialog: | @@ -196,16 +197,8 @@ To open default dialog: | ||
196 | 197 | ||
197 | ```dart | 198 | ```dart |
198 | Get.defaultDialog( | 199 | Get.defaultDialog( |
199 | - title: "My Title", | ||
200 | - content: Text("Hi, it's my dialog"), | ||
201 | - confirm: FlatButton( | ||
202 | - child: Text("Ok"), | ||
203 | - onPressed: () => print("OK pressed"), | ||
204 | - ), | ||
205 | - cancel: FlatButton( | ||
206 | - child: Text("Cancel"), | ||
207 | - onPressed: () => Get.back(), | ||
208 | - )); | 200 | + onConfirm: () => print("Ok"), |
201 | + middleText: "Dialog made in 3 lines of code"); | ||
209 | ``` | 202 | ``` |
210 | You can also use Get.generalDialog instead of showGeneralDialog. | 203 | You can also use Get.generalDialog instead of showGeneralDialog. |
211 | 204 | ||
@@ -305,7 +298,7 @@ class OtherClasse extends StatelessWidget { | @@ -305,7 +298,7 @@ class OtherClasse extends StatelessWidget { | ||
305 | } | 298 | } |
306 | 299 | ||
307 | ``` | 300 | ``` |
308 | -If you need to use your controller in many other places, and outside of ReBuilder, just create a get in your controller and have it easily. You can copy this code and just change the name of your controller. | 301 | +If you need to use your controller in many other places, and outside of GetBuilder, just create a get in your controller and have it easily. (or use `Get.find<Controller>()`) |
309 | 302 | ||
310 | ```dart | 303 | ```dart |
311 | class Controller extends GetController { | 304 | class Controller extends GetController { |
@@ -313,7 +306,7 @@ class Controller extends GetController { | @@ -313,7 +306,7 @@ class Controller extends GetController { | ||
313 | /// You do not need that. I recommend using it just for ease of syntax. | 306 | /// You do not need that. I recommend using it just for ease of syntax. |
314 | /// with static method: Controller.to.counter(); | 307 | /// with static method: Controller.to.counter(); |
315 | /// with no static method: Get.find<Controller>().counter(); | 308 | /// with no static method: Get.find<Controller>().counter(); |
316 | - /// There is no difference in performance, nor any side effect of using either syntax. Only one does not need the type, and the other does. | 309 | + /// There is no difference in performance, nor any side effect of using either syntax. Only one does not need the type, and the other the IDE will autocomplete it. |
317 | static Controller get to => Get.find(); // add this line | 310 | static Controller get to => Get.find(); // add this line |
318 | 311 | ||
319 | int counter = 0; | 312 | int counter = 0; |
@@ -389,7 +382,7 @@ GetBuilder( // you dont need to type on this way | @@ -389,7 +382,7 @@ GetBuilder( // you dont need to type on this way | ||
389 | ``` | 382 | ``` |
390 | 383 | ||
391 | ## Simple Instance Manager | 384 | ## Simple Instance Manager |
392 | -Are you already using Get and want to make your project as lean as possible? Now Get has a simple instance manager that allows you to retrieve the same class as your Bloc or Controller with just 1 lines of code. | 385 | +Are you already using Get and want to make your project as lean as possible? Get has a simple and powerful dependency manager that allows you to retrieve the same class as your Bloc or Controller with just 1 lines of code, no Provider context, no inheritedWidget: |
393 | 386 | ||
394 | ```dart | 387 | ```dart |
395 | Controller controller = Get.put(Controller()); // Rather Controller controller = Controller(); | 388 | Controller controller = Get.put(Controller()); // Rather Controller controller = Controller(); |
@@ -415,7 +408,7 @@ Text(controller.textFromApi); | @@ -415,7 +408,7 @@ Text(controller.textFromApi); | ||
415 | 408 | ||
416 | To remove a instance of Get: | 409 | To remove a instance of Get: |
417 | ```dart | 410 | ```dart |
418 | -Get.delete(Controller()); | 411 | +Get.delete<Controller>(); |
419 | ``` | 412 | ``` |
420 | 413 | ||
421 | 414 |
@@ -7,6 +7,8 @@ export 'src/bottomsheet/bottomsheet.dart'; | @@ -7,6 +7,8 @@ export 'src/bottomsheet/bottomsheet.dart'; | ||
7 | export 'src/snackbar/snack_route.dart'; | 7 | export 'src/snackbar/snack_route.dart'; |
8 | export 'src/state/get_state.dart'; | 8 | export 'src/state/get_state.dart'; |
9 | export 'src/root/root_widget.dart'; | 9 | export 'src/root/root_widget.dart'; |
10 | +export 'src/routes/default_route.dart'; | ||
11 | +export 'src/routes/get_route.dart'; | ||
10 | export 'src/routes/observers/route_observer.dart'; | 12 | export 'src/routes/observers/route_observer.dart'; |
11 | export 'src/routes/transitions_type.dart'; | 13 | export 'src/routes/transitions_type.dart'; |
12 | export 'src/platform/platform.dart'; | 14 | export 'src/platform/platform.dart'; |
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; | @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; | ||
2 | import 'package:flutter/scheduler.dart'; | 2 | import 'package:flutter/scheduler.dart'; |
3 | import 'bottomsheet/bottomsheet.dart'; | 3 | import 'bottomsheet/bottomsheet.dart'; |
4 | import 'platform/platform.dart'; | 4 | import 'platform/platform.dart'; |
5 | +import 'root/root_controller.dart'; | ||
5 | import 'routes/default_route.dart'; | 6 | import 'routes/default_route.dart'; |
6 | import 'routes/observers/route_observer.dart'; | 7 | import 'routes/observers/route_observer.dart'; |
7 | import 'routes/transitions_type.dart'; | 8 | import 'routes/transitions_type.dart'; |
@@ -60,7 +61,7 @@ class Get { | @@ -60,7 +61,7 @@ class Get { | ||
60 | Duration duration, | 61 | Duration duration, |
61 | int id, | 62 | int id, |
62 | bool popGesture}) { | 63 | bool popGesture}) { |
63 | - return global(id).currentState.push(GetRoute( | 64 | + return global(id).currentState.push(GetRouteBase( |
64 | opaque: opaque ?? true, | 65 | opaque: opaque ?? true, |
65 | page: page, | 66 | page: page, |
66 | popGesture: popGesture ?? _defaultPopGesture, | 67 | popGesture: popGesture ?? _defaultPopGesture, |
@@ -136,10 +137,10 @@ class Get { | @@ -136,10 +137,10 @@ class Get { | ||
136 | global(id).currentState.pop(result); | 137 | global(id).currentState.pop(result); |
137 | } | 138 | } |
138 | 139 | ||
139 | - /// Experimental API to back from overlay | ||
140 | - static void backE({dynamic result}) { | ||
141 | - Navigator.pop(overlayContext); | ||
142 | - } | 140 | + // /// Experimental API to back from overlay |
141 | + // static void backE({dynamic result}) { | ||
142 | + // Navigator.pop(overlayContext); | ||
143 | + // } | ||
143 | 144 | ||
144 | /// It will close as many screens as you define. Times must be> 0; | 145 | /// It will close as many screens as you define. Times must be> 0; |
145 | static void close(int times, [int id]) { | 146 | static void close(int times, [int id]) { |
@@ -162,7 +163,7 @@ class Get { | @@ -162,7 +163,7 @@ class Get { | ||
162 | bool popGesture, | 163 | bool popGesture, |
163 | int id, | 164 | int id, |
164 | Duration duration}) { | 165 | Duration duration}) { |
165 | - return global(id).currentState.pushReplacement(GetRoute( | 166 | + return global(id).currentState.pushReplacement(GetRouteBase( |
166 | opaque: opaque ?? true, | 167 | opaque: opaque ?? true, |
167 | page: page, | 168 | page: page, |
168 | popGesture: popGesture ?? _defaultPopGesture, | 169 | popGesture: popGesture ?? _defaultPopGesture, |
@@ -180,7 +181,7 @@ class Get { | @@ -180,7 +181,7 @@ class Get { | ||
180 | var route = (Route<dynamic> rota) => false; | 181 | var route = (Route<dynamic> rota) => false; |
181 | 182 | ||
182 | return global(id).currentState.pushAndRemoveUntil( | 183 | return global(id).currentState.pushAndRemoveUntil( |
183 | - GetRoute( | 184 | + GetRouteBase( |
184 | opaque: opaque ?? true, | 185 | opaque: opaque ?? true, |
185 | popGesture: popGesture ?? _defaultPopGesture, | 186 | popGesture: popGesture ?? _defaultPopGesture, |
186 | page: page, | 187 | page: page, |
@@ -232,15 +233,89 @@ class Get { | @@ -232,15 +233,89 @@ class Get { | ||
232 | ); | 233 | ); |
233 | } | 234 | } |
234 | 235 | ||
235 | - static Future<T> defaultDialog<T>( | ||
236 | - {String title = "Alert dialog", | 236 | + static Future<T> defaultDialog<T>({ |
237 | + String title = "Alert", | ||
237 | Widget content, | 238 | Widget content, |
239 | + VoidCallback onConfirm, | ||
240 | + VoidCallback onCancel, | ||
241 | + VoidCallback onCustom, | ||
242 | + String textConfirm, | ||
243 | + String textCancel, | ||
244 | + String textCustom, | ||
245 | + Widget confirm, | ||
238 | Widget cancel, | 246 | Widget cancel, |
239 | - Widget confirm}) { | ||
240 | - return dialog(AlertDialog( | 247 | + Widget custom, |
248 | + Color backgroundColor, | ||
249 | + Color buttonColor, | ||
250 | + String middleText = "Dialog made in 3 lines of code", | ||
251 | + double radius = 20.0, | ||
252 | + List<Widget> actions, | ||
253 | + }) { | ||
254 | + Widget cancelButton = cancel ?? (onCancel != null || textCancel != null) | ||
255 | + ? FlatButton( | ||
256 | + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, | ||
257 | + onPressed: () { | ||
258 | + onCancel?.call(); | ||
259 | + Get.back(); | ||
260 | + }, | ||
261 | + padding: EdgeInsets.symmetric(horizontal: 10, vertical: 8), | ||
262 | + child: Text(textConfirm ?? "Cancel"), | ||
263 | + shape: RoundedRectangleBorder( | ||
264 | + side: BorderSide( | ||
265 | + color: buttonColor ?? Get.theme.accentColor, | ||
266 | + width: 2, | ||
267 | + style: BorderStyle.solid), | ||
268 | + borderRadius: BorderRadius.circular(100)), | ||
269 | + ) | ||
270 | + : null; | ||
271 | + | ||
272 | + Widget confirmButton = confirm ?? (onConfirm != null || textConfirm != null) | ||
273 | + ? FlatButton( | ||
274 | + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, | ||
275 | + color: buttonColor ?? Get.theme.accentColor, | ||
276 | + shape: RoundedRectangleBorder( | ||
277 | + borderRadius: BorderRadius.circular(100)), | ||
278 | + child: Text(textConfirm ?? "Ok"), | ||
279 | + onPressed: () { | ||
280 | + onConfirm?.call(); | ||
281 | + }) | ||
282 | + : null; | ||
283 | + if (actions == null) { | ||
284 | + actions = []; | ||
285 | + if (cancelButton != null) { | ||
286 | + actions.add(cancelButton); | ||
287 | + } | ||
288 | + if (confirmButton != null) { | ||
289 | + actions.add(confirmButton); | ||
290 | + } | ||
291 | + } | ||
292 | + return Get.dialog(AlertDialog( | ||
293 | + titlePadding: EdgeInsets.all(8), | ||
294 | + contentPadding: EdgeInsets.all(8), | ||
295 | + backgroundColor: backgroundColor ?? Get.theme.dialogBackgroundColor, | ||
296 | + shape: RoundedRectangleBorder( | ||
297 | + borderRadius: BorderRadius.all(Radius.circular(radius))), | ||
241 | title: Text(title, textAlign: TextAlign.center), | 298 | title: Text(title, textAlign: TextAlign.center), |
242 | - content: content, | ||
243 | - actions: <Widget>[cancel, confirm], | 299 | + content: Column( |
300 | + crossAxisAlignment: CrossAxisAlignment.center, | ||
301 | + mainAxisSize: MainAxisSize.min, | ||
302 | + children: [ | ||
303 | + content ?? Text(middleText ?? "", textAlign: TextAlign.center), | ||
304 | + SizedBox(height: 16), | ||
305 | + ButtonTheme( | ||
306 | + minWidth: 78.0, | ||
307 | + height: 34.0, | ||
308 | + child: Wrap( | ||
309 | + alignment: WrapAlignment.center, | ||
310 | + spacing: 8, | ||
311 | + runSpacing: 8, | ||
312 | + children: actions, | ||
313 | + ), | ||
314 | + ) | ||
315 | + ], | ||
316 | + ), | ||
317 | + // actions: actions, // ?? <Widget>[cancelButton, confirmButton], | ||
318 | + buttonPadding: EdgeInsets.zero, | ||
244 | )); | 319 | )); |
245 | } | 320 | } |
246 | 321 | ||
@@ -281,9 +356,94 @@ class Get { | @@ -281,9 +356,94 @@ class Get { | ||
281 | )); | 356 | )); |
282 | } | 357 | } |
283 | 358 | ||
359 | + static void rawSnackbar( | ||
360 | + {String title, | ||
361 | + String message, | ||
362 | + Widget titleText, | ||
363 | + Widget messageText, | ||
364 | + Widget icon, | ||
365 | + bool instantInit = false, | ||
366 | + bool shouldIconPulse = true, | ||
367 | + double maxWidth, | ||
368 | + EdgeInsets margin = const EdgeInsets.all(0.0), | ||
369 | + EdgeInsets padding = const EdgeInsets.all(16), | ||
370 | + double borderRadius = 0.0, | ||
371 | + Color borderColor, | ||
372 | + double borderWidth = 1.0, | ||
373 | + Color backgroundColor = const Color(0xFF303030), | ||
374 | + Color leftBarIndicatorColor, | ||
375 | + List<BoxShadow> boxShadows, | ||
376 | + Gradient backgroundGradient, | ||
377 | + FlatButton mainButton, | ||
378 | + OnTap onTap, | ||
379 | + Duration duration = const Duration(seconds: 3), | ||
380 | + bool isDismissible = true, | ||
381 | + SnackDismissDirection dismissDirection = SnackDismissDirection.VERTICAL, | ||
382 | + bool showProgressIndicator = false, | ||
383 | + AnimationController progressIndicatorController, | ||
384 | + Color progressIndicatorBackgroundColor, | ||
385 | + Animation<Color> progressIndicatorValueColor, | ||
386 | + SnackPosition snackPosition = SnackPosition.BOTTOM, | ||
387 | + SnackStyle snackStyle = SnackStyle.FLOATING, | ||
388 | + Curve forwardAnimationCurve = Curves.easeOutCirc, | ||
389 | + Curve reverseAnimationCurve = Curves.easeOutCirc, | ||
390 | + Duration animationDuration = const Duration(seconds: 1), | ||
391 | + SnackStatusCallback onStatusChanged, | ||
392 | + double barBlur = 0.0, | ||
393 | + double overlayBlur = 0.0, | ||
394 | + Color overlayColor = Colors.transparent, | ||
395 | + Form userInputForm}) { | ||
396 | + GetBar getBar = GetBar( | ||
397 | + title: title, | ||
398 | + message: message, | ||
399 | + titleText: titleText, | ||
400 | + messageText: messageText, | ||
401 | + snackPosition: snackPosition, | ||
402 | + borderRadius: borderRadius, | ||
403 | + margin: margin, | ||
404 | + duration: duration, | ||
405 | + barBlur: barBlur, | ||
406 | + backgroundColor: backgroundColor, | ||
407 | + icon: icon, | ||
408 | + shouldIconPulse: shouldIconPulse, | ||
409 | + maxWidth: maxWidth, | ||
410 | + padding: padding, | ||
411 | + borderColor: borderColor, | ||
412 | + borderWidth: borderWidth, | ||
413 | + leftBarIndicatorColor: leftBarIndicatorColor, | ||
414 | + boxShadows: boxShadows, | ||
415 | + backgroundGradient: backgroundGradient, | ||
416 | + mainButton: mainButton, | ||
417 | + onTap: onTap, | ||
418 | + isDismissible: isDismissible, | ||
419 | + dismissDirection: dismissDirection, | ||
420 | + showProgressIndicator: showProgressIndicator ?? false, | ||
421 | + progressIndicatorController: progressIndicatorController, | ||
422 | + progressIndicatorBackgroundColor: progressIndicatorBackgroundColor, | ||
423 | + progressIndicatorValueColor: progressIndicatorValueColor, | ||
424 | + snackStyle: snackStyle, | ||
425 | + forwardAnimationCurve: forwardAnimationCurve, | ||
426 | + reverseAnimationCurve: reverseAnimationCurve, | ||
427 | + animationDuration: animationDuration, | ||
428 | + overlayBlur: overlayBlur, | ||
429 | + overlayColor: overlayColor, | ||
430 | + userInputForm: userInputForm); | ||
431 | + | ||
432 | + if (instantInit) { | ||
433 | + getBar.show(); | ||
434 | + } else { | ||
435 | + SchedulerBinding.instance.addPostFrameCallback((_) { | ||
436 | + getBar.show(); | ||
437 | + }); | ||
438 | + } | ||
439 | + } | ||
440 | + | ||
284 | static void snackbar(title, message, | 441 | static void snackbar(title, message, |
285 | {Color colorText, | 442 | {Color colorText, |
286 | Duration duration, | 443 | Duration duration, |
444 | + | ||
445 | + /// with instantInit = false you can put Get.snackbar on initState | ||
446 | + bool instantInit = false, | ||
287 | SnackPosition snackPosition, | 447 | SnackPosition snackPosition, |
288 | Widget titleText, | 448 | Widget titleText, |
289 | Widget messageText, | 449 | Widget messageText, |
@@ -315,14 +475,14 @@ class Get { | @@ -315,14 +475,14 @@ class Get { | ||
315 | double overlayBlur, | 475 | double overlayBlur, |
316 | Color overlayColor, | 476 | Color overlayColor, |
317 | Form userInputForm}) { | 477 | Form userInputForm}) { |
318 | - SchedulerBinding.instance.addPostFrameCallback((_) { | ||
319 | - final Color defaultColor = IconTheme.of(Get.key.currentContext).color; | ||
320 | - return GetBar( | ||
321 | - titleText: titleText ?? | 478 | + GetBar getBar = GetBar( |
479 | + titleText: (title == null) | ||
480 | + ? null | ||
481 | + : titleText ?? | ||
322 | Text( | 482 | Text( |
323 | title, | 483 | title, |
324 | style: TextStyle( | 484 | style: TextStyle( |
325 | - color: colorText ?? defaultColor, | 485 | + color: colorText ?? theme.iconTheme.color, |
326 | fontWeight: FontWeight.w800, | 486 | fontWeight: FontWeight.w800, |
327 | fontSize: 16), | 487 | fontSize: 16), |
328 | ), | 488 | ), |
@@ -330,7 +490,7 @@ class Get { | @@ -330,7 +490,7 @@ class Get { | ||
330 | Text( | 490 | Text( |
331 | message, | 491 | message, |
332 | style: TextStyle( | 492 | style: TextStyle( |
333 | - color: colorText ?? defaultColor, | 493 | + color: colorText ?? theme.iconTheme.color, |
334 | fontWeight: FontWeight.w300, | 494 | fontWeight: FontWeight.w300, |
335 | fontSize: 14), | 495 | fontSize: 14), |
336 | ), | 496 | ), |
@@ -363,10 +523,16 @@ class Get { | @@ -363,10 +523,16 @@ class Get { | ||
363 | animationDuration: animationDuration ?? Duration(seconds: 1), | 523 | animationDuration: animationDuration ?? Duration(seconds: 1), |
364 | overlayBlur: overlayBlur ?? 0.0, | 524 | overlayBlur: overlayBlur ?? 0.0, |
365 | overlayColor: overlayColor ?? Colors.transparent, | 525 | overlayColor: overlayColor ?? Colors.transparent, |
366 | - userInputForm: userInputForm) | ||
367 | - ..show(); | 526 | + userInputForm: userInputForm); |
527 | + | ||
528 | + if (instantInit) { | ||
529 | + getBar.show(); | ||
530 | + } else { | ||
531 | + SchedulerBinding.instance.addPostFrameCallback((_) { | ||
532 | + getBar.show(); | ||
368 | }); | 533 | }); |
369 | } | 534 | } |
535 | + } | ||
370 | 536 | ||
371 | /// change default config of Get | 537 | /// change default config of Get |
372 | static void config( | 538 | static void config( |
@@ -398,6 +564,16 @@ class Get { | @@ -398,6 +564,16 @@ class Get { | ||
398 | } | 564 | } |
399 | } | 565 | } |
400 | 566 | ||
567 | + static GetMaterialController getController = GetMaterialController(); | ||
568 | + | ||
569 | + static changeTheme(ThemeData theme) { | ||
570 | + getController.setTheme(theme); | ||
571 | + } | ||
572 | + | ||
573 | + static restartApp() { | ||
574 | + getController.restartApp(); | ||
575 | + } | ||
576 | + | ||
401 | static Map<int, GlobalKey<NavigatorState>> _keys = {}; | 577 | static Map<int, GlobalKey<NavigatorState>> _keys = {}; |
402 | 578 | ||
403 | static GlobalKey<NavigatorState> nestedKey(int key) { | 579 | static GlobalKey<NavigatorState> nestedKey(int key) { |
@@ -416,40 +592,128 @@ class Get { | @@ -416,40 +592,128 @@ class Get { | ||
416 | } | 592 | } |
417 | 593 | ||
418 | //////////// INSTANCE MANAGER | 594 | //////////// INSTANCE MANAGER |
419 | - static Map<dynamic, dynamic> _singl = {}; | 595 | + Map<dynamic, dynamic> _singl = {}; |
596 | + | ||
597 | + Map<dynamic, _FcBuilderFunc> _factory = {}; | ||
598 | + | ||
599 | + static void lazyPut<S>(Object instance) { | ||
600 | + final lazy = () => instance; | ||
601 | + Get()._factory.putIfAbsent(S, () => lazy); | ||
602 | + } | ||
603 | + | ||
604 | + static void lazyPutBuilder<S>(_FcBuilderFunc function) { | ||
605 | + Get()._factory.putIfAbsent(S, () => function); | ||
606 | + } | ||
420 | 607 | ||
421 | - /// Register a singleton instance of your class | ||
422 | - static T put<T>(T singleton) { | ||
423 | - _singl.putIfAbsent(T, () => singleton); | ||
424 | - return _singl[T]; | 608 | + /// Inject class on Get Instance Manager |
609 | + static S put<S>( | ||
610 | + S dependency, { | ||
611 | + String name, | ||
612 | + bool overrideAbstract = false, | ||
613 | + _FcBuilderFunc<S> builder, | ||
614 | + }) { | ||
615 | + _insert( | ||
616 | + isSingleton: true, | ||
617 | + replace: overrideAbstract, | ||
618 | + //?? (("$S" == "${dependency.runtimeType}") == false), | ||
619 | + name: name, | ||
620 | + builder: builder ?? (() => dependency)); | ||
621 | + return find<S>(name: name); | ||
622 | + } | ||
623 | + | ||
624 | + /// Create a new instance from builder class | ||
625 | + /// Example | ||
626 | + /// Get.create(() => Repl()); | ||
627 | + /// Repl a = Get.find(); | ||
628 | + /// Repl b = Get.find(); | ||
629 | + /// print(a==b); (false) | ||
630 | + static void create<S>( | ||
631 | + _FcBuilderFunc<S> builder, { | ||
632 | + String name, | ||
633 | + }) { | ||
634 | + _insert(isSingleton: false, name: name, builder: builder); | ||
635 | + } | ||
636 | + | ||
637 | + static void _insert<S>({ | ||
638 | + bool isSingleton, | ||
639 | + String name, | ||
640 | + bool replace = true, | ||
641 | + _FcBuilderFunc<S> builder, | ||
642 | + }) { | ||
643 | + assert(builder != null); | ||
644 | + String key = _getKey(S, name); | ||
645 | + if (replace) { | ||
646 | + Get()._singl[key] = _FcBuilder<S>(isSingleton, builder); | ||
647 | + } else { | ||
648 | + Get()._singl.putIfAbsent(key, () => _FcBuilder<S>(isSingleton, builder)); | ||
649 | + } | ||
650 | + } | ||
651 | + | ||
652 | + /// Find a instance from required class | ||
653 | + static S find<S>({String name}) { | ||
654 | + if (Get.isRegistred<S>()) { | ||
655 | + String key = _getKey(S, name); | ||
656 | + _FcBuilder builder = Get()._singl[key]; | ||
657 | + if (builder == null) { | ||
658 | + if (name == null) { | ||
659 | + throw "class ${S.toString()} is not register"; | ||
660 | + } else { | ||
661 | + throw "class ${S.toString()} with name '$name' is not register"; | ||
662 | + } | ||
663 | + } | ||
664 | + return Get()._singl[key].getSependency(); | ||
665 | + } else { | ||
666 | + if (!Get()._factory.containsKey(S)) | ||
667 | + throw " $S not found. You need call Get.put<$S>($S()) before"; | ||
668 | + | ||
669 | + if (isLogEnable) print('[GET] $S instance was created at that time'); | ||
670 | + S _value = Get.put<S>(Get()._factory[S].call() as S); | ||
671 | + Get()._factory.remove(S); | ||
672 | + return _value; | ||
673 | + } | ||
674 | + } | ||
675 | + | ||
676 | + /// Remove dependency of [S] on dependency abstraction. For concrete class use Get.delete | ||
677 | + static void remove<S>({String name}) { | ||
678 | + String key = _getKey(S, name); | ||
679 | + _FcBuilder builder = Get()._singl[key]; | ||
680 | + if (builder != null) builder.dependency = null; | ||
681 | + if (Get()._singl.containsKey(key)) { | ||
682 | + print('error on remove $key'); | ||
683 | + } else { | ||
684 | + if (isLogEnable) print('[GET] $key removed from memory'); | ||
685 | + } | ||
686 | + } | ||
687 | + | ||
688 | + static String _getKey(Type type, String name) { | ||
689 | + return name == null ? type.toString() : type.toString() + name; | ||
425 | } | 690 | } |
426 | 691 | ||
427 | static bool reset() { | 692 | static bool reset() { |
428 | - _singl.clear(); | 693 | + Get()._singl.clear(); |
429 | return true; | 694 | return true; |
430 | } | 695 | } |
431 | 696 | ||
432 | - /// Delete a singleton instance of your class | ||
433 | - static bool delete<T>(T singleton) { | ||
434 | - if (!_singl.containsKey(T)) { | ||
435 | - print('key id not found'); | 697 | + /// Delete class instance on [S] and clean memory |
698 | + static bool delete<S>({String name}) { | ||
699 | + String key = _getKey(S, name); | ||
700 | + | ||
701 | + if (!Get()._singl.containsKey(key)) { | ||
702 | + print('Instance $key not found'); | ||
436 | return false; | 703 | return false; |
437 | } | 704 | } |
438 | - _singl.removeWhere((oldkey, value) => (oldkey == T)); | 705 | + Get()._singl.removeWhere((oldkey, value) => (oldkey == key)); |
706 | + if (Get()._singl.containsKey(key)) { | ||
707 | + print('error on remove object $key'); | ||
708 | + } else { | ||
709 | + if (isLogEnable) print('[GET] $key deleted from memory'); | ||
710 | + } | ||
439 | return true; | 711 | return true; |
440 | } | 712 | } |
441 | 713 | ||
442 | /// check if instance is registred | 714 | /// check if instance is registred |
443 | - static bool isRegistred<T>() => _singl.containsKey(T); | ||
444 | - | ||
445 | - /// Recover a singleton instance of your class | ||
446 | - static T find<T>() { | ||
447 | - if (!_singl.containsKey(T)) { | ||
448 | - throw 'key id ${T.runtimeType} not found'; | ||
449 | - } | ||
450 | - final recoverKey = _singl[T]; | ||
451 | - return recoverKey; | ||
452 | - } | 715 | + static bool isRegistred<S>({String name}) => |
716 | + Get()._singl.containsKey(_getKey(S, name)); | ||
453 | 717 | ||
454 | /// give access to Routing API from GetObserver | 718 | /// give access to Routing API from GetObserver |
455 | static Routing get routing => _routing; | 719 | static Routing get routing => _routing; |
@@ -526,8 +790,11 @@ class Get { | @@ -526,8 +790,11 @@ class Get { | ||
526 | /// give access to Theme.of(context) | 790 | /// give access to Theme.of(context) |
527 | static ThemeData get theme => Theme.of(context); | 791 | static ThemeData get theme => Theme.of(context); |
528 | 792 | ||
793 | + /// give access to TextTheme.of(context) | ||
794 | + static TextTheme get textTheme => Theme.of(context).textTheme; | ||
795 | + | ||
529 | /// give access to Mediaquery.of(context) | 796 | /// give access to Mediaquery.of(context) |
530 | - static MediaQueryData get mediaquery => MediaQuery.of(context); | 797 | + static MediaQueryData get mediaQuery => MediaQuery.of(context); |
531 | 798 | ||
532 | /// give access to Theme.of(context).iconTheme.color | 799 | /// give access to Theme.of(context).iconTheme.color |
533 | static Color get iconColor => Theme.of(context).iconTheme.color; | 800 | static Color get iconColor => Theme.of(context).iconTheme.color; |
@@ -542,3 +809,24 @@ class Get { | @@ -542,3 +809,24 @@ class Get { | ||
542 | /// It replaces the Flutter Navigator, but needs no context. | 809 | /// It replaces the Flutter Navigator, but needs no context. |
543 | /// You can to use navigator.push(YourRoute()) rather Navigator.push(context, YourRoute()); | 810 | /// You can to use navigator.push(YourRoute()) rather Navigator.push(context, YourRoute()); |
544 | NavigatorState get navigator => Get.key.currentState; | 811 | NavigatorState get navigator => Get.key.currentState; |
812 | + | ||
813 | +class _FcBuilder<S> { | ||
814 | + bool isSingleton; | ||
815 | + _FcBuilderFunc builderFunc; | ||
816 | + S dependency; | ||
817 | + | ||
818 | + _FcBuilder(this.isSingleton, this.builderFunc); | ||
819 | + | ||
820 | + S getSependency() { | ||
821 | + if (isSingleton) { | ||
822 | + if (dependency == null) { | ||
823 | + dependency = builderFunc() as S; | ||
824 | + } | ||
825 | + return dependency; | ||
826 | + } else { | ||
827 | + return builderFunc() as S; | ||
828 | + } | ||
829 | + } | ||
830 | +} | ||
831 | + | ||
832 | +typedef _FcBuilderFunc<S> = S Function(); |
lib/src/root/root_controller.dart
0 → 100644
1 | +import 'package:flutter/material.dart'; | ||
2 | +import 'package:get/src/routes/utils/parse_arguments.dart'; | ||
3 | +import 'package:get/src/state/get_state.dart'; | ||
4 | + | ||
5 | +class GetMaterialController extends GetController { | ||
6 | + ParseRoute parse = ParseRoute(); | ||
7 | + Key key = UniqueKey(); | ||
8 | + ThemeData theme; | ||
9 | + | ||
10 | + void setTheme(ThemeData value) { | ||
11 | + theme = value; | ||
12 | + update(this); | ||
13 | + } | ||
14 | + | ||
15 | + void restartApp() { | ||
16 | + key = UniqueKey(); | ||
17 | + update(this); | ||
18 | + } | ||
19 | +} |
1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
2 | import 'package:get/get.dart'; | 2 | import 'package:get/get.dart'; |
3 | +import 'package:get/src/routes/get_route.dart'; | ||
3 | import 'package:get/src/routes/utils/parse_arguments.dart'; | 4 | import 'package:get/src/routes/utils/parse_arguments.dart'; |
5 | +import 'root_controller.dart'; | ||
4 | 6 | ||
5 | -class GetMaterialApp extends StatefulWidget { | 7 | +class GetMaterialApp extends StatelessWidget { |
6 | const GetMaterialApp({ | 8 | const GetMaterialApp({ |
7 | Key key, | 9 | Key key, |
8 | this.navigatorKey, | 10 | this.navigatorKey, |
@@ -17,6 +19,8 @@ class GetMaterialApp extends StatefulWidget { | @@ -17,6 +19,8 @@ class GetMaterialApp extends StatefulWidget { | ||
17 | this.title = '', | 19 | this.title = '', |
18 | this.onGenerateTitle, | 20 | this.onGenerateTitle, |
19 | this.color, | 21 | this.color, |
22 | + this.onInit, | ||
23 | + this.onDispose, | ||
20 | this.theme, | 24 | this.theme, |
21 | this.darkTheme, | 25 | this.darkTheme, |
22 | this.themeMode = ThemeMode.system, | 26 | this.themeMode = ThemeMode.system, |
@@ -84,6 +88,8 @@ class GetMaterialApp extends StatefulWidget { | @@ -84,6 +88,8 @@ class GetMaterialApp extends StatefulWidget { | ||
84 | final Function(Routing) routingCallback; | 88 | final Function(Routing) routingCallback; |
85 | final Transition defaultTransition; | 89 | final Transition defaultTransition; |
86 | final bool opaqueRoute; | 90 | final bool opaqueRoute; |
91 | + final VoidCallback onInit; | ||
92 | + final VoidCallback onDispose; | ||
87 | final bool enableLog; | 93 | final bool enableLog; |
88 | final bool popGesture; | 94 | final bool popGesture; |
89 | final Duration transitionDuration; | 95 | final Duration transitionDuration; |
@@ -91,31 +97,6 @@ class GetMaterialApp extends StatefulWidget { | @@ -91,31 +97,6 @@ class GetMaterialApp extends StatefulWidget { | ||
91 | final Map<String, GetRoute> namedRoutes; | 97 | final Map<String, GetRoute> namedRoutes; |
92 | final GetRoute unknownRoute; | 98 | final GetRoute unknownRoute; |
93 | 99 | ||
94 | - @override | ||
95 | - _GetMaterialAppState createState() => _GetMaterialAppState(); | ||
96 | -} | ||
97 | - | ||
98 | -class _GetMaterialAppState extends State<GetMaterialApp> { | ||
99 | - ParseRoute parse = ParseRoute(); | ||
100 | - @override | ||
101 | - void initState() { | ||
102 | - if (widget.namedRoutes != null) { | ||
103 | - widget.namedRoutes.forEach((key, value) { | ||
104 | - parse.addRoute(key); | ||
105 | - }); | ||
106 | - } | ||
107 | - Get.config( | ||
108 | - enableLog: widget.enableLog ?? Get.isLogEnable, | ||
109 | - defaultTransition: widget.defaultTransition ?? Get.defaultTransition, | ||
110 | - defaultOpaqueRoute: widget.opaqueRoute ?? Get.isOpaqueRouteDefault, | ||
111 | - defaultPopGesture: widget.popGesture ?? Get.isPopGestureEnable, | ||
112 | - defaultDurationTransition: | ||
113 | - widget.transitionDuration ?? Get.defaultDurationTransition, | ||
114 | - defaultGlobalState: widget.defaultGlobalState ?? Get.defaultGlobalState, | ||
115 | - ); | ||
116 | - super.initState(); | ||
117 | - } | ||
118 | - | ||
119 | Route<dynamic> namedRoutesGenerate(RouteSettings settings) { | 100 | Route<dynamic> namedRoutesGenerate(RouteSettings settings) { |
120 | Get.setSettings(settings); | 101 | Get.setSettings(settings); |
121 | // final parsedString = parse.split(settings.name); | 102 | // final parsedString = parse.split(settings.name); |
@@ -124,87 +105,132 @@ class _GetMaterialAppState extends State<GetMaterialApp> { | @@ -124,87 +105,132 @@ class _GetMaterialAppState extends State<GetMaterialApp> { | ||
124 | /// workaround until they fix it, because the problem is with the 'Flutter engine', | 105 | /// workaround until they fix it, because the problem is with the 'Flutter engine', |
125 | /// which changes the initial route for an empty String, not the main Flutter, | 106 | /// which changes the initial route for an empty String, not the main Flutter, |
126 | /// so only Team can fix it. | 107 | /// so only Team can fix it. |
127 | - final parsedString = parse.split( | ||
128 | - settings.name == '' ? (widget.initialRoute ?? '/') : settings.name); | 108 | + var parsedString = Get.getController.parse.split( |
109 | + (settings.name == '' || settings.name == null) | ||
110 | + ? (initialRoute ?? '/') | ||
111 | + : settings.name); | ||
112 | + | ||
113 | + if (parsedString == null) { | ||
114 | + parsedString = AppRouteMatch(); | ||
115 | + parsedString.route = settings.name; | ||
116 | + } | ||
129 | 117 | ||
130 | - String settingsname = parsedString.route; | 118 | + String settingsName = parsedString.route; |
131 | Map<String, GetRoute> newNamedRoutes = {}; | 119 | Map<String, GetRoute> newNamedRoutes = {}; |
132 | 120 | ||
133 | - widget.namedRoutes.forEach((key, value) { | ||
134 | - String newName = parse.split(key).route; | 121 | + namedRoutes.forEach((key, value) { |
122 | + String newName = Get.getController.parse.split(key).route; | ||
135 | newNamedRoutes.addAll({newName: value}); | 123 | newNamedRoutes.addAll({newName: value}); |
136 | }); | 124 | }); |
137 | 125 | ||
138 | - if (newNamedRoutes.containsKey(settingsname)) { | 126 | + if (newNamedRoutes.containsKey(settingsName)) { |
139 | Get.setParameter(parsedString.parameters); | 127 | Get.setParameter(parsedString.parameters); |
140 | - return GetRoute( | ||
141 | - page: newNamedRoutes[settingsname].page, | ||
142 | - title: newNamedRoutes[settingsname].title, | 128 | + |
129 | + return GetRouteBase( | ||
130 | + page: newNamedRoutes[settingsName].page, | ||
131 | + title: newNamedRoutes[settingsName].title, | ||
143 | parameter: parsedString.parameters, | 132 | parameter: parsedString.parameters, |
144 | settings: | 133 | settings: |
145 | RouteSettings(name: settings.name, arguments: settings.arguments), | 134 | RouteSettings(name: settings.name, arguments: settings.arguments), |
146 | - maintainState: newNamedRoutes[settingsname].maintainState, | ||
147 | - curve: newNamedRoutes[settingsname].curve, | ||
148 | - alignment: newNamedRoutes[settingsname].alignment, | ||
149 | - opaque: newNamedRoutes[settingsname].opaque, | ||
150 | - transitionDuration: (widget.transitionDuration == null | ||
151 | - ? newNamedRoutes[settingsname].transitionDuration | ||
152 | - : widget.transitionDuration), | ||
153 | - transition: newNamedRoutes[settingsname].transition, | ||
154 | - popGesture: newNamedRoutes[settingsname].popGesture, | ||
155 | - fullscreenDialog: newNamedRoutes[settingsname].fullscreenDialog, | 135 | + maintainState: newNamedRoutes[settingsName].maintainState, |
136 | + curve: newNamedRoutes[settingsName].curve, | ||
137 | + alignment: newNamedRoutes[settingsName].alignment, | ||
138 | + opaque: newNamedRoutes[settingsName].opaque, | ||
139 | + transitionDuration: (transitionDuration == null | ||
140 | + ? newNamedRoutes[settingsName].transitionDuration | ||
141 | + : transitionDuration), | ||
142 | + transition: newNamedRoutes[settingsName].transition, | ||
143 | + popGesture: newNamedRoutes[settingsName].popGesture, | ||
144 | + fullscreenDialog: newNamedRoutes[settingsName].fullscreenDialog, | ||
156 | ); | 145 | ); |
157 | } else { | 146 | } else { |
158 | - return (widget.unknownRoute ?? | ||
159 | - GetRoute( | 147 | + return ((unknownRoute == null |
148 | + ? GetRouteBase( | ||
160 | page: Scaffold( | 149 | page: Scaffold( |
161 | body: Center( | 150 | body: Center( |
162 | child: Text("Route not found :("), | 151 | child: Text("Route not found :("), |
163 | ), | 152 | ), |
153 | + )) | ||
154 | + : GetRouteBase( | ||
155 | + page: unknownRoute.page, | ||
156 | + title: unknownRoute.title, | ||
157 | + settings: unknownRoute.settings, | ||
158 | + maintainState: unknownRoute.maintainState, | ||
159 | + curve: unknownRoute.curve, | ||
160 | + alignment: unknownRoute.alignment, | ||
161 | + parameter: unknownRoute.parameter, | ||
162 | + opaque: unknownRoute.opaque, | ||
163 | + transitionDuration: unknownRoute.transitionDuration, | ||
164 | + popGesture: unknownRoute.popGesture, | ||
165 | + transition: unknownRoute.transition, | ||
166 | + fullscreenDialog: unknownRoute.fullscreenDialog, | ||
164 | ))); | 167 | ))); |
165 | } | 168 | } |
166 | } | 169 | } |
167 | 170 | ||
168 | @override | 171 | @override |
169 | Widget build(BuildContext context) { | 172 | Widget build(BuildContext context) { |
173 | + return GetBuilder<GetMaterialController>( | ||
174 | + init: Get.getController, | ||
175 | + dispose: (d) { | ||
176 | + onDispose?.call(); | ||
177 | + }, | ||
178 | + initState: (i) { | ||
179 | + onInit?.call(); | ||
180 | + if (namedRoutes != null) { | ||
181 | + namedRoutes.forEach((key, value) { | ||
182 | + Get.getController.parse.addRoute(key); | ||
183 | + }); | ||
184 | + } | ||
185 | + Get.config( | ||
186 | + enableLog: enableLog ?? Get.isLogEnable, | ||
187 | + defaultTransition: defaultTransition ?? Get.defaultTransition, | ||
188 | + defaultOpaqueRoute: opaqueRoute ?? Get.isOpaqueRouteDefault, | ||
189 | + defaultPopGesture: popGesture ?? Get.isPopGestureEnable, | ||
190 | + defaultDurationTransition: | ||
191 | + transitionDuration ?? Get.defaultDurationTransition, | ||
192 | + defaultGlobalState: defaultGlobalState ?? Get.defaultGlobalState, | ||
193 | + ); | ||
194 | + }, | ||
195 | + builder: (_) { | ||
170 | return MaterialApp( | 196 | return MaterialApp( |
171 | - navigatorKey: (widget.navigatorKey == null | ||
172 | - ? Get.key | ||
173 | - : Get.addKey(widget.navigatorKey)), | ||
174 | - home: widget.home, | ||
175 | - routes: widget.routes ?? const <String, WidgetBuilder>{}, | ||
176 | - initialRoute: widget.initialRoute, | ||
177 | - onGenerateRoute: (widget.namedRoutes == null | ||
178 | - ? widget.onGenerateRoute | ||
179 | - : namedRoutesGenerate), | ||
180 | - onGenerateInitialRoutes: widget.onGenerateInitialRoutes, | ||
181 | - onUnknownRoute: widget.onUnknownRoute, | ||
182 | - navigatorObservers: (widget.navigatorObservers == null | ||
183 | - ? <NavigatorObserver>[GetObserver(widget.routingCallback)] | ||
184 | - : <NavigatorObserver>[GetObserver(widget.routingCallback)] | ||
185 | - ..addAll(widget.navigatorObservers)), | ||
186 | - builder: widget.builder, | ||
187 | - title: widget.title ?? '', | ||
188 | - onGenerateTitle: widget.onGenerateTitle, | ||
189 | - color: widget.color, | ||
190 | - theme: widget.theme, | ||
191 | - darkTheme: widget.darkTheme, | ||
192 | - themeMode: widget.themeMode ?? ThemeMode.system, | ||
193 | - locale: widget.locale, | ||
194 | - localizationsDelegates: widget.localizationsDelegates, | ||
195 | - localeListResolutionCallback: widget.localeListResolutionCallback, | ||
196 | - localeResolutionCallback: widget.localeResolutionCallback, | 197 | + key: _.key, |
198 | + navigatorKey: | ||
199 | + (navigatorKey == null ? Get.key : Get.addKey(navigatorKey)), | ||
200 | + home: home, | ||
201 | + routes: routes ?? const <String, WidgetBuilder>{}, | ||
202 | + initialRoute: initialRoute, | ||
203 | + onGenerateRoute: | ||
204 | + (namedRoutes == null ? onGenerateRoute : namedRoutesGenerate), | ||
205 | + onGenerateInitialRoutes: onGenerateInitialRoutes, | ||
206 | + onUnknownRoute: onUnknownRoute, | ||
207 | + navigatorObservers: (navigatorObservers == null | ||
208 | + ? <NavigatorObserver>[GetObserver(routingCallback)] | ||
209 | + : <NavigatorObserver>[GetObserver(routingCallback)] | ||
210 | + ..addAll(navigatorObservers)), | ||
211 | + builder: builder, | ||
212 | + title: title ?? '', | ||
213 | + onGenerateTitle: onGenerateTitle, | ||
214 | + color: color, | ||
215 | + theme: theme ?? _.theme ?? ThemeData.fallback(), | ||
216 | + darkTheme: darkTheme, | ||
217 | + themeMode: themeMode ?? ThemeMode.system, | ||
218 | + locale: locale, | ||
219 | + localizationsDelegates: localizationsDelegates, | ||
220 | + localeListResolutionCallback: localeListResolutionCallback, | ||
221 | + localeResolutionCallback: localeResolutionCallback, | ||
197 | supportedLocales: | 222 | supportedLocales: |
198 | - widget.supportedLocales ?? const <Locale>[Locale('en', 'US')], | ||
199 | - debugShowMaterialGrid: widget.debugShowMaterialGrid ?? false, | ||
200 | - showPerformanceOverlay: widget.showPerformanceOverlay ?? false, | 223 | + supportedLocales ?? const <Locale>[Locale('en', 'US')], |
224 | + debugShowMaterialGrid: debugShowMaterialGrid ?? false, | ||
225 | + showPerformanceOverlay: showPerformanceOverlay ?? false, | ||
201 | checkerboardRasterCacheImages: | 226 | checkerboardRasterCacheImages: |
202 | - widget.checkerboardRasterCacheImages ?? false, | ||
203 | - checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers ?? false, | ||
204 | - showSemanticsDebugger: widget.showSemanticsDebugger ?? false, | ||
205 | - debugShowCheckedModeBanner: widget.debugShowCheckedModeBanner ?? true, | ||
206 | - shortcuts: widget.shortcuts, | ||
207 | - // actions: widget.actions, | 227 | + checkerboardRasterCacheImages ?? false, |
228 | + checkerboardOffscreenLayers: checkerboardOffscreenLayers ?? false, | ||
229 | + showSemanticsDebugger: showSemanticsDebugger ?? false, | ||
230 | + debugShowCheckedModeBanner: debugShowCheckedModeBanner ?? true, | ||
231 | + shortcuts: shortcuts, | ||
232 | + // actions: actions, | ||
208 | ); | 233 | ); |
234 | + }); | ||
209 | } | 235 | } |
210 | } | 236 | } |
@@ -18,10 +18,10 @@ const int _kMaxDroppedSwipePageForwardAnimationTime = 800; // Milliseconds. | @@ -18,10 +18,10 @@ const int _kMaxDroppedSwipePageForwardAnimationTime = 800; // Milliseconds. | ||
18 | // user releases a page mid swipe. | 18 | // user releases a page mid swipe. |
19 | const int _kMaxPageBackAnimationTime = 300; | 19 | const int _kMaxPageBackAnimationTime = 300; |
20 | 20 | ||
21 | -class GetRoute<T> extends PageRoute<T> { | 21 | +class GetRouteBase<T> extends PageRoute<T> { |
22 | /// The [builder], [maintainState], and [fullscreenDialog] arguments must not | 22 | /// The [builder], [maintainState], and [fullscreenDialog] arguments must not |
23 | /// be null. | 23 | /// be null. |
24 | - GetRoute({ | 24 | + GetRouteBase({ |
25 | @required this.page, | 25 | @required this.page, |
26 | this.title, | 26 | this.title, |
27 | RouteSettings settings, | 27 | RouteSettings settings, |
@@ -85,7 +85,7 @@ class GetRoute<T> extends PageRoute<T> { | @@ -85,7 +85,7 @@ class GetRoute<T> extends PageRoute<T> { | ||
85 | @override | 85 | @override |
86 | void didChangePrevious(Route<dynamic> previousRoute) { | 86 | void didChangePrevious(Route<dynamic> previousRoute) { |
87 | final String previousTitleString = | 87 | final String previousTitleString = |
88 | - previousRoute is GetRoute ? previousRoute.title : null; | 88 | + previousRoute is GetRouteBase ? previousRoute.title : null; |
89 | if (_previousTitle == null) { | 89 | if (_previousTitle == null) { |
90 | _previousTitle = ValueNotifier<String>(previousTitleString); | 90 | _previousTitle = ValueNotifier<String>(previousTitleString); |
91 | } else { | 91 | } else { |
@@ -113,7 +113,7 @@ class GetRoute<T> extends PageRoute<T> { | @@ -113,7 +113,7 @@ class GetRoute<T> extends PageRoute<T> { | ||
113 | @override | 113 | @override |
114 | bool canTransitionTo(TransitionRoute<dynamic> nextRoute) { | 114 | bool canTransitionTo(TransitionRoute<dynamic> nextRoute) { |
115 | // Don't perform outgoing animation if the next route is a fullscreen dialog. | 115 | // Don't perform outgoing animation if the next route is a fullscreen dialog. |
116 | - return nextRoute is GetRoute && !nextRoute.fullscreenDialog; | 116 | + return nextRoute is GetRouteBase && !nextRoute.fullscreenDialog; |
117 | } | 117 | } |
118 | 118 | ||
119 | /// True if an iOS-style back swipe pop gesture is currently underway for [route]. | 119 | /// True if an iOS-style back swipe pop gesture is currently underway for [route]. |
lib/src/routes/get_route.dart
0 → 100644
1 | +import 'package:flutter/widgets.dart'; | ||
2 | + | ||
3 | +import 'transitions_type.dart'; | ||
4 | + | ||
5 | +class GetRoute { | ||
6 | + final Widget page; | ||
7 | + final bool popGesture; | ||
8 | + final Map<String, String> parameter; | ||
9 | + final String title; | ||
10 | + final Transition transition; | ||
11 | + final Curve curve; | ||
12 | + final Alignment alignment; | ||
13 | + final bool maintainState; | ||
14 | + final bool opaque; | ||
15 | + final Duration transitionDuration; | ||
16 | + final bool fullscreenDialog; | ||
17 | + final RouteSettings settings; | ||
18 | + | ||
19 | + GetRoute({ | ||
20 | + @required this.page, | ||
21 | + this.title, | ||
22 | + this.settings, | ||
23 | + this.maintainState = true, | ||
24 | + this.curve = Curves.linear, | ||
25 | + this.alignment, | ||
26 | + this.parameter, | ||
27 | + this.opaque = true, | ||
28 | + this.transitionDuration = const Duration(milliseconds: 400), | ||
29 | + this.popGesture, | ||
30 | + this.transition, | ||
31 | + this.fullscreenDialog = false, | ||
32 | + }) : assert(page != null), | ||
33 | + assert(maintainState != null), | ||
34 | + assert(fullscreenDialog != null); | ||
35 | +} |
1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
2 | import '../get_main.dart'; | 2 | import '../get_main.dart'; |
3 | 3 | ||
4 | +class RealState { | ||
5 | + final State state; | ||
6 | + final String id; | ||
7 | + RealState({this.state, this.id}); | ||
8 | +} | ||
9 | + | ||
4 | class GetController extends State { | 10 | class GetController extends State { |
5 | - Map<GetController, State> _allStates = {}; | 11 | + Map<GetController, List<RealState>> _allStates = {}; |
6 | 12 | ||
7 | /// Update GetBuilder with update(this) | 13 | /// Update GetBuilder with update(this) |
8 | - void update(GetController id) { | ||
9 | - if (id != null) { | ||
10 | - final State state = _allStates[id]; | ||
11 | - if (state != null && state.mounted) state.setState(() {}); | 14 | + void update(GetController controller, [List<String> ids]) { |
15 | + if (controller != null) { | ||
16 | + if (ids == null) { | ||
17 | + var all = _allStates[controller]; | ||
18 | + all.forEach((rs) { | ||
19 | + if (rs.state != null && rs.state.mounted) rs.state.setState(() {}); | ||
20 | + }); | ||
21 | + } else { | ||
22 | + ids.forEach( | ||
23 | + (s) { | ||
24 | + var all = _allStates[controller]; | ||
25 | + all.forEach((rs) { | ||
26 | + if (rs.state != null && rs.state.mounted && rs.id == s) | ||
27 | + rs.state.setState(() {}); | ||
28 | + }); | ||
29 | + }, | ||
30 | + ); | ||
31 | + } | ||
12 | } | 32 | } |
13 | } | 33 | } |
14 | 34 | ||
@@ -20,6 +40,7 @@ class GetBuilder<T extends GetController> extends StatefulWidget { | @@ -20,6 +40,7 @@ class GetBuilder<T extends GetController> extends StatefulWidget { | ||
20 | @required | 40 | @required |
21 | final Widget Function(T) builder; | 41 | final Widget Function(T) builder; |
22 | final bool global; | 42 | final bool global; |
43 | + final String id; | ||
23 | final bool autoRemove; | 44 | final bool autoRemove; |
24 | final void Function(State state) initState, dispose, didChangeDependencies; | 45 | final void Function(State state) initState, dispose, didChangeDependencies; |
25 | final void Function(GetBuilder oldWidget, State state) didUpdateWidget; | 46 | final void Function(GetBuilder oldWidget, State state) didUpdateWidget; |
@@ -32,6 +53,7 @@ class GetBuilder<T extends GetController> extends StatefulWidget { | @@ -32,6 +53,7 @@ class GetBuilder<T extends GetController> extends StatefulWidget { | ||
32 | this.autoRemove = true, | 53 | this.autoRemove = true, |
33 | this.initState, | 54 | this.initState, |
34 | this.dispose, | 55 | this.dispose, |
56 | + this.id, | ||
35 | this.didChangeDependencies, | 57 | this.didChangeDependencies, |
36 | this.didUpdateWidget, | 58 | this.didUpdateWidget, |
37 | }) : assert(builder != null), | 59 | }) : assert(builder != null), |
@@ -48,14 +70,24 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | @@ -48,14 +70,24 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | ||
48 | if (widget.global) { | 70 | if (widget.global) { |
49 | if (Get.isRegistred<T>()) { | 71 | if (Get.isRegistred<T>()) { |
50 | controller = Get.find<T>(); | 72 | controller = Get.find<T>(); |
73 | + if (controller._allStates[controller] == null) { | ||
74 | + controller._allStates[controller] = []; | ||
75 | + } | ||
76 | + controller._allStates[controller] | ||
77 | + .add(RealState(state: this, id: widget.id)); | ||
51 | } else { | 78 | } else { |
52 | controller = widget.init; | 79 | controller = widget.init; |
53 | - controller._allStates[controller] = this; | ||
54 | - Get.put(controller); | 80 | + if (controller._allStates[controller] == null) { |
81 | + controller._allStates[controller] = []; | ||
82 | + } | ||
83 | + controller._allStates[controller] | ||
84 | + .add(RealState(state: this, id: widget.id)); | ||
85 | + Get.put<T>(controller); | ||
55 | } | 86 | } |
56 | } else { | 87 | } else { |
57 | controller = widget.init; | 88 | controller = widget.init; |
58 | - controller._allStates[controller] = this; | 89 | + controller._allStates[controller] |
90 | + .add(RealState(state: this, id: widget.id)); | ||
59 | } | 91 | } |
60 | if (widget.initState != null) widget.initState(this); | 92 | if (widget.initState != null) widget.initState(this); |
61 | } | 93 | } |
@@ -67,11 +99,24 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | @@ -67,11 +99,24 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | ||
67 | if (b._allStates[controller].hashCode == this.hashCode) { | 99 | if (b._allStates[controller].hashCode == this.hashCode) { |
68 | b._allStates.remove(controller); | 100 | b._allStates.remove(controller); |
69 | } | 101 | } |
102 | + } else { | ||
103 | + var b = controller; | ||
104 | + if (b._allStates[controller].hashCode == this.hashCode) { | ||
105 | + b._allStates.remove(controller); | ||
106 | + } | ||
70 | } | 107 | } |
71 | if (widget.dispose != null) widget.dispose(this); | 108 | if (widget.dispose != null) widget.dispose(this); |
72 | - if (widget.autoRemove && Get.isRegistred<T>() && (widget.init != null)) { | ||
73 | - Get.delete(widget.init); | 109 | + |
110 | + if (widget.init != null) { | ||
111 | + if (widget.autoRemove && Get.isRegistred<T>()) { | ||
112 | + Get.delete<T>(); | ||
113 | + } | ||
114 | + } else { | ||
115 | + // controller._allStates[controller].remove(this); | ||
116 | + controller._allStates[controller] | ||
117 | + .remove(RealState(state: this, id: widget.id)); | ||
74 | } | 118 | } |
119 | + | ||
75 | super.dispose(); | 120 | super.dispose(); |
76 | } | 121 | } |
77 | 122 |
1 | name: get | 1 | name: get |
2 | -description: Navigate between screens, display snackbars, dialogs and bottomSheets, from anywhere in your code without context with Get. | ||
3 | -version: 2.0.10 | 2 | +description: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get. |
3 | +version: 2.2.2 | ||
4 | homepage: https://github.com/jonataslaw/get | 4 | homepage: https://github.com/jonataslaw/get |
5 | 5 | ||
6 | environment: | 6 | environment: |
-
Please register or login to post a comment