Jonny Borges
Committed by GitHub

Merge pull request #170 from Nipodemos/update-ptbr-translation

Rewrite ptbr translation
@@ -16,13 +16,13 @@ Get is an extra-light and powerful library for Flutter that will give you superp @@ -16,13 +16,13 @@ Get is an extra-light and powerful library for Flutter that will give you superp
16 ```dart 16 ```dart
17 // Default Flutter navigator 17 // Default Flutter navigator
18 Navigator.of(context).push( 18 Navigator.of(context).push(
19 - context,  
20 - MaterialPageRoute(  
21 - builder: (BuildContext context) {  
22 - return Home();  
23 - },  
24 - ),  
25 - ); 19 + context,
  20 + MaterialPageRoute(
  21 + builder: (BuildContext context) {
  22 + return Home();
  23 + },
  24 + ),
  25 +);
26 26
27 // Get syntax 27 // Get syntax
28 Get.to(Home()); 28 Get.to(Home());
@@ -143,22 +143,22 @@ Example: @@ -143,22 +143,22 @@ Example:
143 143
144 // Default Flutter navigator 144 // Default Flutter navigator
145 Navigator.of(context).push( 145 Navigator.of(context).push(
146 - context,  
147 - MaterialPageRoute(  
148 - builder: (BuildContext context) {  
149 - return HomePage();  
150 - },  
151 - ),  
152 - ); 146 + context,
  147 + MaterialPageRoute(
  148 + builder: (BuildContext context) {
  149 + return HomePage();
  150 + },
  151 + ),
  152 +);
153 153
154 // Get using Flutter syntax without needing context 154 // Get using Flutter syntax without needing context
155 navigator.push( 155 navigator.push(
156 - MaterialPageRoute(  
157 - builder: (_) {  
158 - return HomePage();  
159 - },  
160 - ),  
161 - ); 156 + MaterialPageRoute(
  157 + builder: (_) {
  158 + return HomePage();
  159 + },
  160 + ),
  161 +);
162 162
163 // Get syntax (It is much better, but you have the right to disagree) 163 // Get syntax (It is much better, but you have the right to disagree)
164 Get.to(HomePage()); 164 Get.to(HomePage());
@@ -171,14 +171,15 @@ Get.to(HomePage()); @@ -171,14 +171,15 @@ Get.to(HomePage());
171 To have a simple SnackBar with Flutter, you must get the context of Scaffold, or you must use a GlobalKey attached to your Scaffold, 171 To have a simple SnackBar with Flutter, you must get the context of Scaffold, or you must use a GlobalKey attached to your Scaffold,
172 ```dart 172 ```dart
173 final snackBar = SnackBar( 173 final snackBar = SnackBar(
174 - content: Text('Hi!'),  
175 - action: SnackBarAction(  
176 - label: 'I am a old and ugly snackbar :(',  
177 - onPressed: (){}  
178 - ),  
179 - // Find the Scaffold in the widget tree and use  
180 - // it to show a SnackBar.  
181 - Scaffold.of(context).showSnackBar(snackBar); 174 + content: Text('Hi!'),
  175 + action: SnackBarAction(
  176 + label: 'I am a old and ugly snackbar :(',
  177 + onPressed: (){}
  178 + ),
  179 +);
  180 +// Find the Scaffold in the widget tree and use
  181 +// it to show a SnackBar.
  182 +Scaffold.of(context).showSnackBar(snackBar);
182 ``` 183 ```
183 184
184 With Get: 185 With Get:
@@ -190,16 +191,16 @@ Get.snackbar('Hi', 'i am a modern snackbar'); @@ -190,16 +191,16 @@ Get.snackbar('Hi', 'i am a modern snackbar');
190 With Get, all you have to do is call your Get.snackbar from anywhere in your code or customize it however you want! 191 With Get, all you have to do is call your Get.snackbar from anywhere in your code or customize it however you want!
191 192
192 ```dart 193 ```dart
193 - Get.snackbar(  
194 - "Hey i'm a Get SnackBar!", // title  
195 - "It's unbelievable! I'm using SnackBar without context, without boilerplate, without Scaffold, it is something truly amazing!", // message  
196 - icon: Icon(Icons.alarm),  
197 - shouldIconPulse: true,  
198 - onTap:(){},  
199 - barBlur: 20,  
200 - isDismissible: true,  
201 - duration: Duration(seconds: 3),  
202 - ); 194 +Get.snackbar(
  195 + "Hey i'm a Get SnackBar!", // title
  196 + "It's unbelievable! I'm using SnackBar without context, without boilerplate, without Scaffold, it is something truly amazing!", // message
  197 + icon: Icon(Icons.alarm),
  198 + shouldIconPulse: true,
  199 + onTap:(){},
  200 + barBlur: 20,
  201 + isDismissible: true,
  202 + duration: Duration(seconds: 3),
  203 +);
203 204
204 205
205 ////////// ALL FEATURES ////////// 206 ////////// ALL FEATURES //////////
@@ -252,9 +253,10 @@ Get.dialog(YourDialogWidget()); @@ -252,9 +253,10 @@ Get.dialog(YourDialogWidget());
252 To open default dialog: 253 To open default dialog:
253 254
254 ```dart 255 ```dart
255 - Get.defaultDialog(  
256 - onConfirm: () => print("Ok"),  
257 - middleText: "Dialog made in 3 lines of code"); 256 +Get.defaultDialog(
  257 + onConfirm: () => print("Ok"),
  258 + middleText: "Dialog made in 3 lines of code"
  259 +);
258 ``` 260 ```
259 You can also use Get.generalDialog instead of showGeneralDialog. 261 You can also use Get.generalDialog instead of showGeneralDialog.
260 262
@@ -267,24 +269,23 @@ Get.bottomSheet is like showModalBottomSheet, but don't need of context. @@ -267,24 +269,23 @@ Get.bottomSheet is like showModalBottomSheet, but don't need of context.
267 269
268 ```dart 270 ```dart
269 Get.bottomSheet( 271 Get.bottomSheet(
270 - Container(  
271 - child: Wrap(  
272 - children: <Widget>[  
273 - ListTile(  
274 - leading: Icon(Icons.music_note),  
275 - title: Text('Music'),  
276 - onTap: () => {}  
277 - ),  
278 - ListTile(  
279 - leading: Icon(Icons.videocam),  
280 - title: Text('Video'),  
281 - onTap: () => {},  
282 - ),  
283 - ], 272 + Container(
  273 + child: Wrap(
  274 + children: <Widget>[
  275 + ListTile(
  276 + leading: Icon(Icons.music_note),
  277 + title: Text('Music'),
  278 + onTap: () => {}
284 ), 279 ),
285 - );  
286 - }  
287 - ); 280 + ListTile(
  281 + leading: Icon(Icons.videocam),
  282 + title: Text('Video'),
  283 + onTap: () => {},
  284 + ),
  285 + ],
  286 + ),
  287 + );
  288 +);
288 ``` 289 ```
289 290
290 ## Simple State Manager 291 ## Simple State Manager
@@ -331,10 +332,11 @@ class Controller extends GetController { @@ -331,10 +332,11 @@ class Controller extends GetController {
331 } 332 }
332 // On your Stateless/Stateful class, use GetBuilder to update Text when increment be called 333 // On your Stateless/Stateful class, use GetBuilder to update Text when increment be called
333 GetBuilder<Controller>( 334 GetBuilder<Controller>(
334 - init: Controller(), // INIT IT ONLY THE FIRST TIME  
335 - builder: (_) => Text(  
336 - '${_.counter}',  
337 - )), 335 + init: Controller(), // INIT IT ONLY THE FIRST TIME
  336 + builder: (_) => Text(
  337 + '${_.counter}',
  338 + ),
  339 +)
338 //Initialize your controller only the first time. The second time you are using ReBuilder for the same controller, do not use it again. Your controller will be automatically removed from memory as soon as the widget that marked it as 'init' is deployed. You don't have to worry about that, Get will do it automatically, just make sure you don't start the same controller twice. 340 //Initialize your controller only the first time. The second time you are using ReBuilder for the same controller, do not use it again. Your controller will be automatically removed from memory as soon as the widget that marked it as 'init' is deployed. You don't have to worry about that, Get will do it automatically, just make sure you don't start the same controller twice.
339 ``` 341 ```
340 **Done!** 342 **Done!**
@@ -346,7 +348,7 @@ GetBuilder<Controller>( @@ -346,7 +348,7 @@ GetBuilder<Controller>(
346 If you navigate many routes and need data that was in your previously used controller, you just need to use GetBuilder Again (with no init): 348 If you navigate many routes and need data that was in your previously used controller, you just need to use GetBuilder Again (with no init):
347 349
348 ```dart 350 ```dart
349 -class OtherClasse extends StatelessWidget { 351 +class OtherClass extends StatelessWidget {
350 @override 352 @override
351 Widget build(BuildContext context) { 353 Widget build(BuildContext context) {
352 return Scaffold( 354 return Scaffold(
@@ -380,11 +382,11 @@ class Controller extends GetController { @@ -380,11 +382,11 @@ class Controller extends GetController {
380 And then you can access your controller directly, that way: 382 And then you can access your controller directly, that way:
381 ```dart 383 ```dart
382 FloatingActionButton( 384 FloatingActionButton(
383 - onPressed:(){  
384 - Controller.to.increment(),  
385 - } // This is incredibly simple!  
386 - child: Text("${Controller.to.counter}"),  
387 - ), 385 + onPressed: () {
  386 + Controller.to.increment(),
  387 + } // This is incredibly simple!
  388 + child: Text("${Controller.to.counter}"),
  389 +),
388 ``` 390 ```
389 When you press FloatingActionButton, all widgets that are listening to the 'counter' variable will be updated automatically. 391 When you press FloatingActionButton, all widgets that are listening to the 'counter' variable will be updated automatically.
390 392
@@ -398,10 +400,10 @@ If you need to call initState() or dispose() method for example, you can call th @@ -398,10 +400,10 @@ If you need to call initState() or dispose() method for example, you can call th
398 400
399 ```dart 401 ```dart
400 GetBuilder<Controller>( 402 GetBuilder<Controller>(
401 - initState(_) => Controller.to.fetchApi(),  
402 - dispose(_) => Controller.to.closeStreams(),  
403 - builder: (s) => Text('${s.username}'),  
404 - ), 403 + initState: (_) => Controller.to.fetchApi(),
  404 + dispose: (_) => Controller.to.closeStreams(),
  405 + builder: (s) => Text('${s.username}'),
  406 +),
405 ``` 407 ```
406 408
407 A much better approach than this is to use the onInit() and onClose() method directly from your controller. 409 A much better approach than this is to use the onInit() and onClose() method directly from your controller.
@@ -425,17 +427,17 @@ Do not call a dispose method inside GetController, it will not do anything, reme @@ -425,17 +427,17 @@ Do not call a dispose method inside GetController, it will not do anything, reme
425 427
426 ```dart 428 ```dart
427 class Controller extends GetController { 429 class Controller extends GetController {
428 -StreamController<User> user = StreamController<User>();  
429 -StreamController<String> name = StreamController<String>(); 430 + StreamController<User> user = StreamController<User>();
  431 + StreamController<String> name = StreamController<String>();
430 432
431 -/// close stream = onClose method, not dispose.  
432 -@override  
433 -void onClose() {  
434 - user.close();  
435 - name.close();  
436 - super.onClose(); 433 + /// close stream = onClose method, not dispose.
  434 + @override
  435 + void onClose() {
  436 + user.close();
  437 + name.close();
  438 + super.onClose();
  439 + }
437 } 440 }
438 -  
439 ``` 441 ```
440 Controller life cycle: 442 Controller life cycle:
441 - onInit() where it is created. 443 - onInit() where it is created.
@@ -447,11 +449,12 @@ Controller life cycle: @@ -447,11 +449,12 @@ Controller life cycle:
447 You can use Controller instance directly on GetBuilder value: 449 You can use Controller instance directly on GetBuilder value:
448 450
449 ```dart 451 ```dart
450 -GetBuilder<Controller>(  
451 - init: Controller(),  
452 - builder: (value) => Text(  
453 - '${value.counter}', //here  
454 - )), 452 +GetBuilder<Controller>(
  453 + init: Controller(),
  454 + builder: (value) => Text(
  455 + '${value.counter}', //here
  456 + ),
  457 +),
455 ``` 458 ```
456 You may also need an instance of your controller outside of your GetBuilder, and you can use these approaches to achieve this: 459 You may also need an instance of your controller outside of your GetBuilder, and you can use these approaches to achieve this:
457 460
@@ -462,35 +465,38 @@ class Controller extends GetController { @@ -462,35 +465,38 @@ class Controller extends GetController {
462 } 465 }
463 // on you view: 466 // on you view:
464 GetBuilder<Controller>( 467 GetBuilder<Controller>(
465 - init: Controller(), // use it only first time on each controller  
466 - builder: (_) => Text(  
467 - '${Controller.to.counter}', //here  
468 - )), 468 + init: Controller(), // use it only first time on each controller
  469 + builder: (_) => Text(
  470 + '${Controller.to.counter}', //here
  471 + )
  472 +),
  473 +```
469 or 474 or
470 - 475 +```dart
471 class Controller extends GetController { 476 class Controller extends GetController {
472 // static Controller get to => Get.find(); // with no static get 477 // static Controller get to => Get.find(); // with no static get
473 [...] 478 [...]
474 } 479 }
475 // on stateful/stateless class 480 // on stateful/stateless class
476 GetBuilder<Controller>( 481 GetBuilder<Controller>(
477 - init: Controller(), // use it only first time on each controller  
478 - builder: (_) => Text(  
479 - '${Get.find<Controller>().counter}', //here  
480 - )), 482 + init: Controller(), // use it only first time on each controller
  483 + builder: (_) => Text(
  484 + '${Get.find<Controller>().counter}', //here
  485 + ),
  486 +),
481 ``` 487 ```
482 488
483 - You can use "non-canonical" approaches to do this. If you are using some other dependency manager, like get_it, modular, etc., and just want to deliver the controller instance, you can do this: 489 - You can use "non-canonical" approaches to do this. If you are using some other dependency manager, like get_it, modular, etc., and just want to deliver the controller instance, you can do this:
484 490
485 ```dart 491 ```dart
486 -  
487 Controller controller = Controller(); 492 Controller controller = Controller();
488 [...] 493 [...]
489 GetBuilder<Controller>( 494 GetBuilder<Controller>(
490 - init: controller, //here  
491 - builder: (_) => Text(  
492 - '${controller.counter}', // here  
493 - )), 495 + init: controller, //here
  496 + builder: (_) => Text(
  497 + '${controller.counter}', // here
  498 + ),
  499 +),
494 500
495 ``` 501 ```
496 <!-- This approach is not recommended, as you will have to manually dispose of your controllers, close your streams manually, and literally give up one of the great benefits of this library, which is intelligent memory control. But if you trust your potential, go ahead! --> 502 <!-- This approach is not recommended, as you will have to manually dispose of your controllers, close your streams manually, and literally give up one of the great benefits of this library, which is intelligent memory control. But if you trust your potential, go ahead! -->
@@ -499,11 +505,12 @@ GetBuilder<Controller>( @@ -499,11 +505,12 @@ GetBuilder<Controller>(
499 If you want to refine a widget's update control with GetBuilder, you can assign them unique IDs: 505 If you want to refine a widget's update control with GetBuilder, you can assign them unique IDs:
500 ```dart 506 ```dart
501 GetBuilder<Controller>( 507 GetBuilder<Controller>(
502 - id: 'text'  
503 - init: Controller(), // use it only first time on each controller  
504 - builder: (_) => Text(  
505 - '${Get.find<Controller>().counter}', //here  
506 - )), 508 + id: 'text'
  509 + init: Controller(), // use it only first time on each controller
  510 + builder: (_) => Text(
  511 + '${Get.find<Controller>().counter}', //here
  512 + ),
  513 +),
507 ``` 514 ```
508 And update it this form: 515 And update it this form:
509 ```dart 516 ```dart
@@ -524,7 +531,7 @@ You can use both in any situation, but if you want to tune their application to @@ -524,7 +531,7 @@ You can use both in any situation, but if you want to tune their application to
524 If you want a powerful state manager, you can go without fear to GetX. It does not work with variables, but flows, everything in it is streams under the hood. You can use rxDart in conjunction with it, because everything is stream, you can hear the event of each "variable", because everything in it is stream, it is literally BLoC, easier than MobX, and without code generator or decorations . 531 If you want a powerful state manager, you can go without fear to GetX. It does not work with variables, but flows, everything in it is streams under the hood. You can use rxDart in conjunction with it, because everything is stream, you can hear the event of each "variable", because everything in it is stream, it is literally BLoC, easier than MobX, and without code generator or decorations .
525 532
526 533
527 -## Reactive State Manager 534 +## Reactive State Manager - GetX
528 535
529 If you want power, Get gives you the most advanced state manager you could ever have. 536 If you want power, Get gives you the most advanced state manager you could ever have.
530 GetX was built 100% based on Streams, and give you all the firepower that BLoC gave you, with an easier facility than using MobX. 537 GetX was built 100% based on Streams, and give you all the firepower that BLoC gave you, with an easier facility than using MobX.
@@ -540,24 +547,24 @@ int get sum => count1.value + count2.value; @@ -540,24 +547,24 @@ int get sum => count1.value + count2.value;
540 ``` 547 ```
541 548
542 ```dart 549 ```dart
543 - GetX<Controller>(  
544 - builder: (_) {  
545 - print("count 1 rebuild");  
546 - return Text('${_.count1.value}');  
547 - },  
548 - ),  
549 - GetX<Controller>(  
550 - builder: (_) {  
551 - print("count 2 rebuild");  
552 - return Text('${_.count2.value}');  
553 - },  
554 - ),  
555 - GetX<Controller>(  
556 - builder: (_) {  
557 - print("count 3 rebuild");  
558 - return Text('${_.sum}');  
559 - },  
560 - ), 550 +GetX<Controller>(
  551 + builder: (_) {
  552 + print("count 1 rebuild");
  553 + return Text('${_.count1.value}');
  554 + },
  555 +),
  556 +GetX<Controller>(
  557 + builder: (_) {
  558 + print("count 2 rebuild");
  559 + return Text('${_.count2.value}');
  560 + },
  561 +),
  562 +GetX<Controller>(
  563 + builder: (_) {
  564 + print("count 3 rebuild");
  565 + return Text('${_.sum}');
  566 + },
  567 +),
561 ``` 568 ```
562 569
563 If we increment the number of count 1, only count 1 and count 3 are reconstructed, because count 1 now has a value of 1, and 1 + 0 = 1, changing the sum value. 570 If we increment the number of count 1, only count 1 and count 3 are reconstructed, because count 1 now has a value of 1, and 1 + 0 = 1, changing the sum value.
@@ -636,7 +643,8 @@ final list = List<User>().obs; @@ -636,7 +643,8 @@ final list = List<User>().obs;
636 643
637 ```dart 644 ```dart
638 ListView.builder ( 645 ListView.builder (
639 -itemCount: list.lenght 646 + itemCount: list.lenght
  647 +)
640 ``` 648 ```
641 649
642 You don't have to work with sets if you don't want to. you can use the "assign 'and" assignAll "api. 650 You don't have to work with sets if you don't want to. you can use the "assign 'and" assignAll "api.
@@ -760,7 +768,7 @@ interval(count1, (_) => print("interval $_"), time: Duration(seconds: 1)); @@ -760,7 +768,7 @@ interval(count1, (_) => print("interval $_"), time: Duration(seconds: 1));
760 'debounce' is very useful in search functions, where you only want the API to be called when the user finishes typing. If the user types "Jonny", you will have 5 searches in the APIs, by the letter J, o, n, n, and y. With Get this does not happen, because you will have a "debounce" Worker that will only be triggered at the end of typing. 768 'debounce' is very useful in search functions, where you only want the API to be called when the user finishes typing. If the user types "Jonny", you will have 5 searches in the APIs, by the letter J, o, n, n, and y. With Get this does not happen, because you will have a "debounce" Worker that will only be triggered at the end of typing.
761 769
762 - interval 770 - interval
763 -'interval' is different from the debouce. debouce if the user makes 1000 changes to a variable within 1 second, he will send only the last one after the stipulated timer (the default is 800 milliseconds). Interval will instead ignore all user actions for the stipulated period. If you send events for 1 minute, 1000 per second, debounce will only send you the last one, when the user stops strafing events. debounce will deliver events every second, and if set to 3 seconds, it will deliver 20 events that minute. This is recommended to avoid abuse, in functions where the user can quickly click on something and get some advantage (imagine that the user can earn coins by clicking on something, if he clicked 300 times in the same minute, he would have 300 coins, using interval, you you can set a time frame for 3 seconds, and even then clicking 300 or a thousand times, the maximum he would get in 1 minute would be 20 coins, clicking 300 or 1 million times). The debounce is suitable for anti-DDos, for functions like search where each change to onChange would cause a query to your api. Debounce will wait for the user to stop typing the name, to make the request. If it were used in the coin scenario mentioned above, the user would only win 1 coin, because it is only executed, when the user "pauses" for the established time. 771 +'interval' is different from the debouce. debouce if the user makes 1000 changes to a variable within 1 second, he will send only the last one after the stipulated timer (the default is 800 milliseconds). Interval will instead ignore all user actions for the stipulated period. If you send events for 1 minute, 1000 per second, debounce will only send you the last one, when the user stops strafing events. interval will deliver events every second, and if set to 3 seconds, it will deliver 20 events that minute. This is recommended to avoid abuse, in functions where the user can quickly click on something and get some advantage (imagine that the user can earn coins by clicking on something, if he clicked 300 times in the same minute, he would have 300 coins, using interval, you you can set a time frame for 3 seconds, and even then clicking 300 or a thousand times, the maximum he would get in 1 minute would be 20 coins, clicking 300 or 1 million times). The debounce is suitable for anti-DDos, for functions like search where each change to onChange would cause a query to your api. Debounce will wait for the user to stop typing the name, to make the request. If it were used in the coin scenario mentioned above, the user would only win 1 coin, because it is only executed, when the user "pauses" for the established time.
764 772
765 773
766 ## Navigate with named routes: 774 ## Navigate with named routes:
@@ -783,14 +791,16 @@ To define routes, use GetMaterialApp: @@ -783,14 +791,16 @@ To define routes, use GetMaterialApp:
783 791
784 ```dart 792 ```dart
785 void main() { 793 void main() {
786 - runApp(GetMaterialApp(  
787 - initialRoute: '/',  
788 - namedRoutes: {  
789 - '/': GetRoute(page: MyHomePage()),  
790 - '/second': GetRoute(page: Second()),  
791 - '/third': GetRoute(page: Third(),transition: Transition.cupertino);  
792 - },  
793 - )); 794 + runApp(
  795 + GetMaterialApp(
  796 + initialRoute: '/',
  797 + namedRoutes: {
  798 + '/': GetRoute(page: MyHomePage()),
  799 + '/second': GetRoute(page: Second()),
  800 + '/third': GetRoute(page: Third(),transition: Transition.cupertino);
  801 + },
  802 + )
  803 + );
794 } 804 }
795 ``` 805 ```
796 806
@@ -826,18 +836,20 @@ You can also receive NamedParameters with Get easily: @@ -826,18 +836,20 @@ You can also receive NamedParameters with Get easily:
826 836
827 ```dart 837 ```dart
828 void main() { 838 void main() {
829 - runApp(GetMaterialApp(  
830 - initialRoute: '/',  
831 - namedRoutes: {  
832 - '/': GetRoute(page: MyHomePage()),  
833 - /// Important! :user is not a new route, it is just a parameter  
834 - /// specification. Do not use '/second/:user' and '/second'  
835 - /// if you need new route to user, use '/second/user/:user'  
836 - /// if '/second' is a route.  
837 - '/second/:user': GetRoute(page: Second()), // receive ID  
838 - '/third': GetRoute(page: Third(),transition: Transition.cupertino);  
839 - },  
840 - )); 839 + runApp(
  840 + GetMaterialApp(
  841 + initialRoute: '/',
  842 + namedRoutes: {
  843 + '/': GetRoute(page: MyHomePage()),
  844 + /// Important! :user is not a new route, it is just a parameter
  845 + /// specification. Do not use '/second/:user' and '/second'
  846 + /// if you need new route to user, use '/second/user/:user'
  847 + /// if '/second' is a route.
  848 + '/second/:user': GetRoute(page: Second()), // receive ID
  849 + '/third': GetRoute(page: Third(),transition: Transition.cupertino);
  850 + },
  851 + )
  852 + );
841 } 853 }
842 ``` 854 ```
843 Send data on route name 855 Send data on route name
@@ -859,25 +871,27 @@ And now, all you need to do is use Get.toNamed() to navigate your named routes, @@ -859,25 +871,27 @@ And now, all you need to do is use Get.toNamed() to navigate your named routes,
859 If you want listen Get events to trigger actions, you can to use routingCallback to it 871 If you want listen Get events to trigger actions, you can to use routingCallback to it
860 ```dart 872 ```dart
861 GetMaterialApp( 873 GetMaterialApp(
862 - routingCallback: (route){ 874 + routingCallback: (route) {
863 if(routing.current == '/second'){ 875 if(routing.current == '/second'){
864 openAds(); 876 openAds();
865 } 877 }
866 } 878 }
867 - ``` 879 +)
  880 +```
868 If you are not using GetMaterialApp, you can use the manual API to attach Middleware observer. 881 If you are not using GetMaterialApp, you can use the manual API to attach Middleware observer.
869 882
870 -  
871 ```dart 883 ```dart
872 void main() { 884 void main() {
873 - runApp(MaterialApp(  
874 - onGenerateRoute: Router.generateRoute,  
875 - initialRoute: "/",  
876 - navigatorKey: Get.key,  
877 - navigatorObservers: [ 885 + runApp(
  886 + MaterialApp(
  887 + onGenerateRoute: Router.generateRoute,
  888 + initialRoute: "/",
  889 + navigatorKey: Get.key,
  890 + navigatorObservers: [
878 GetObserver(MiddleWare.observer), // HERE !!! 891 GetObserver(MiddleWare.observer), // HERE !!!
879 - ],  
880 - )); 892 + ],
  893 + ),
  894 + );
881 } 895 }
882 ``` 896 ```
883 Create a MiddleWare class 897 Create a MiddleWare class
@@ -998,22 +1012,23 @@ If you want to know in depth how to change the theme, you can follow this tutori @@ -998,22 +1012,23 @@ If you want to know in depth how to change the theme, you can follow this tutori
998 You can create Global settings for Get. Just add Get.config to your code before pushing any route or do it directly in your GetMaterialApp 1012 You can create Global settings for Get. Just add Get.config to your code before pushing any route or do it directly in your GetMaterialApp
999 1013
1000 ```dart 1014 ```dart
1001 -  
1002 -GetMaterialApp(  
1003 - enableLog: true,  
1004 - defaultTransition: Transition.fade,  
1005 - opaqueRoute: Get.isOpaqueRouteDefault,  
1006 - popGesture: Get.isPopGestureEnable,  
1007 - transitionDuration: Get.defaultDurationTransition,  
1008 - defaultGlobalState: Get.defaultGlobalState,  
1009 - ); 1015 +GetMaterialApp(
  1016 + enableLog: true,
  1017 + defaultTransition: Transition.fade,
  1018 + opaqueRoute: Get.isOpaqueRouteDefault,
  1019 + popGesture: Get.isPopGestureEnable,
  1020 + transitionDuration: Get.defaultDurationTransition,
  1021 + defaultGlobalState: Get.defaultGlobalState,
  1022 +);
1010 1023
1011 Get.config( 1024 Get.config(
1012 - enableLog = true,  
1013 - defaultPopGesture = true,  
1014 - defaultTransition = Transitions.cupertino} 1025 + enableLog = true,
  1026 + defaultPopGesture = true,
  1027 + defaultTransition = Transitions.cupertino
  1028 +)
1015 ``` 1029 ```
1016 1030
  1031 +
1017 ### Nested Navigators 1032 ### Nested Navigators
1018 1033
1019 Get made Flutter's nested navigation even easier. 1034 Get made Flutter's nested navigation even easier.
@@ -1023,63 +1038,62 @@ You don't need the context, and you will find your navigation stack by Id. @@ -1023,63 +1038,62 @@ You don't need the context, and you will find your navigation stack by Id.
1023 1038
1024 See how simple it is: 1039 See how simple it is:
1025 ```dart 1040 ```dart
1026 - Navigator(  
1027 - key: nestedKey(1), // create a key by index  
1028 - initialRoute: '/',  
1029 - onGenerateRoute: (settings) {  
1030 - if (settings.name == '/') {  
1031 - return GetRouteBase(  
1032 - page: Scaffold(  
1033 - appBar: AppBar(  
1034 - title: Text("Main"),  
1035 - ),  
1036 - body: Center(  
1037 - child: FlatButton(  
1038 - color: Colors.blue,  
1039 - onPressed: () {  
1040 - Get.toNamed('/second', id:1); // navigate by your nested route by index  
1041 - },  
1042 - child: Text("Go to second")),  
1043 - ),  
1044 - ),  
1045 - );  
1046 - } else if (settings.name == '/second') {  
1047 - return GetRouteBase(  
1048 - page: Center(  
1049 - child: Scaffold(  
1050 - appBar: AppBar(  
1051 - title: Text("Main"),  
1052 - ),  
1053 - body: Center(  
1054 - child: Text("second")  
1055 - ),  
1056 - ),  
1057 - ),  
1058 - );  
1059 - }  
1060 - }), 1041 +Navigator(
  1042 + key: nestedKey(1), // create a key by index
  1043 + initialRoute: '/',
  1044 + onGenerateRoute: (settings) {
  1045 + if (settings.name == '/') {
  1046 + return GetRouteBase(
  1047 + page: Scaffold(
  1048 + appBar: AppBar(
  1049 + title: Text("Main"),
  1050 + ),
  1051 + body: Center(
  1052 + child: FlatButton(
  1053 + color: Colors.blue,
  1054 + onPressed: () {
  1055 + Get.toNamed('/second', id:1); // navigate by your nested route by index
  1056 + },
  1057 + child: Text("Go to second"),
  1058 + ),
  1059 + ),
  1060 + ),
  1061 + );
  1062 + } else if (settings.name == '/second') {
  1063 + return GetRouteBase(
  1064 + page: Center(
  1065 + child: Scaffold(
  1066 + appBar: AppBar(
  1067 + title: Text("Main"),
  1068 + ),
  1069 + body: Center(
  1070 + child: Text("second")
  1071 + ),
  1072 + ),
  1073 + ),
  1074 + );
  1075 + }
  1076 + }
  1077 +),
1061 ``` 1078 ```
1062 1079
1063 -This library will always be updated and implementing new features. Feel free to offer PRs and contribute to them.  
1064 -  
1065 -  
1066 ### Other Advanced APIs and Manual configurations 1080 ### Other Advanced APIs and Manual configurations
1067 GetMaterialApp configures everything for you, but if you want to configure Get Manually using advanced APIs. 1081 GetMaterialApp configures everything for you, but if you want to configure Get Manually using advanced APIs.
1068 1082
1069 ```dart 1083 ```dart
1070 MaterialApp( 1084 MaterialApp(
1071 - navigatorKey: Get.key,  
1072 - navigatorObservers: [GetObserver()],  
1073 - ); 1085 + navigatorKey: Get.key,
  1086 + navigatorObservers: [GetObserver()],
  1087 +);
1074 ``` 1088 ```
1075 1089
1076 You will also be able to use your own Middleware within GetObserver, this will not influence anything. 1090 You will also be able to use your own Middleware within GetObserver, this will not influence anything.
1077 1091
1078 ```dart 1092 ```dart
1079 MaterialApp( 1093 MaterialApp(
1080 - navigatorKey: Get.key,  
1081 - navigatorObservers: [GetObserver(MiddleWare.observer)], // Here  
1082 - ); 1094 + navigatorKey: Get.key,
  1095 + navigatorObservers: [GetObserver(MiddleWare.observer)], // Here
  1096 +);
1083 ``` 1097 ```
1084 1098
1085 ```dart 1099 ```dart
@@ -1117,3 +1131,6 @@ Get.contextOverlay // Gives the context of the snackbar/dialog/bottomsheet in th @@ -1117,3 +1131,6 @@ Get.contextOverlay // Gives the context of the snackbar/dialog/bottomsheet in th
1117 1131
1118 ``` 1132 ```
1119 1133
  1134 +This library will always be updated and implementing new features. Feel free to offer PRs and contribute to them.
  1135 +
  1136 +
1 -# Get 1 +<a href="https://www.buymeacoffee.com/jonataslaw" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Me compre um café" style="height: 41px !important;width: 174px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" > </a>
  2 +![](get.png)
2 3
3 -Uma biblioteca de navegação completa que permite navegar entre telas, abrir caixas de diálogo, bottomSheets e exibir snackbars de qualquer lugar do seu código, sem precisar usar context.  
4 -## Ponto de partida 4 +*Idiomas: [English](README.md), [Brazilian Portuguese](README.pt-br.md).*
5 5
6 -*Idiomas: [Inglês](README.md), [Português](README.pt-br.md).* 6 +[![pub package](https://img.shields.io/pub/v/get.svg?label=get&color=blue)](https://pub.dev/packages/get)
  7 +![building](https://github.com/jonataslaw/get/workflows/Test,%20build%20and%20deploy/badge.svg)
  8 +[![Gitter](https://badges.gitter.im/flutter_get/community.svg)](https://gitter.im/flutter_get/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
  9 +<a href="https://github.com/Solido/awesome-flutter">
  10 + <img alt="Awesome Flutter" src="https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square" />
  11 +</a>
7 12
8 -A navegação convencional do Flutter possui muito código clichê desnecessário, requer contexto para navegar entre telas, abrir caixas de diálogo e usar snackbars em seu projeto pode ser algo desgastante.  
9 -Além disso, quando uma rota é enviada por push, todo o MaterialApp pode ser reconstruído causando congelamentos, bem, isso não acontece com o Get.  
10 -Essa biblioteca que mudará a maneira como você trabalha com o Framework e salvará sua vida do código clichê, aumentando sua produtividade e eliminando os erros de reconstrução do seu aplicativo, além de um conjunto de APIs não disponíveis na biblioteca padrão do Flutter.  
11 13
  14 +Get é uma biblioteca poderosa e extra-leve para Flutter que vai te dar superpoderes e aumentar sua produtividade. Navegue sem precisar do `context`, abra `Dialog`s, `Snackbar`s ou `BottomSheet`s de qualquer lugar no código, gerencie estados e injete dependências de uma forma simples e prática! Get é seguro, estável, atualizado e oferece uma enorme gama de APIs que não estão presentes no framework padrão.
12 15
13 ```dart 16 ```dart
14 -// Navegação padrão do Flutter: 17 +// Navigator padrão do Flutter
15 Navigator.of(context).push( 18 Navigator.of(context).push(
16 - context,  
17 - MaterialPageRoute(  
18 - builder: (BuildContext context) {  
19 - return HomePage();  
20 - },  
21 - ),  
22 - );  
23 -  
24 -// Como fazer o mesmo com o Get: 19 + context,
  20 + MaterialPageRoute(
  21 + builder: (BuildContext context) {
  22 + return Home();
  23 + },
  24 + ),
  25 +);
  26 +
  27 +// Sintaxe do Get
25 Get.to(Home()); 28 Get.to(Home());
26 ``` 29 ```
27 30
28 -##### Se você está na branch master/dev/beta do Flutter, use a versão 1.20.0-dev.  
29 -* Se você usa Modular, adicione ao seu MaterialApp: navigatorKey: Get.addKey(Modular.navigatorKey) 31 +**Exemplo completo do app Flutter counter em somente 11 linhas de código**
  32 +```dart
  33 +void main() => runApp(GetMaterialApp(home: Home()));
  34 +class Home extends StatelessWidget {
  35 + final count = 0.obs;
  36 + @override
  37 + Widget build(context) => Scaffold(
  38 + appBar: AppBar(title: Text("Get muda sua vida")),
  39 + floatingActionButton: FloatingActionButton(onPressed: () => count.value++),
  40 + body: Center(child: Obx(() => Text(count.string))),
  41 + );
  42 +}
  43 +```
  44 +
  45 +## Começando
  46 +
  47 +A navegação convencional do Flutter tem uma grande quantidade de boilerplate (código que se repete demais), requer o `context` para navegar entre telas/rotas, abrir dialogs e usar snackbars no framework, e é entediante.
  48 +
  49 +Essa biblioteca vai mudar a forma que você trabalha com o Framework e salvar seu código dos boilerplates, aumentando sua produtividade, e eliminando os bugs de reconstrução da sua aplicação.
  50 +
  51 +- [Começando](#começando)
  52 + - [Você pode contribuir no projeto de várias formas:](#você-pode-contribuir-no-projeto-de-várias-formas)
  53 +- [Como usar?](#como-usar)
  54 +- [Navegação sem rotas nomeadas](#navegação-sem-rotas-nomeadas)
  55 + - [SnackBars](#snackbars)
  56 + - [Dialogs](#dialogs)
  57 + - [BottomSheets](#bottomsheets)
  58 +- [Gerenciador de estado simples](#gerenciador-de-estado-simples)
  59 + - [Uso do gerenciador de estado simples](#uso-do-gerenciador-de-estado-simples)
  60 + - [Sem StatefulWidget;](#sem-statefulwidget)
  61 + - [Formas de uso:](#formas-de-uso)
  62 +- [Reactive State Manager - GetX](#reactive-state-manager---getx)
  63 +- [Gerenciamento de dependências simples](#gerenciamento-de-dependências-simples)
  64 +- [Bindings](#bindings)
  65 + - [Como utilizar:](#como-utilizar)
  66 +- [Workers](#workers)
  67 +- [Navegar com rotas nomeadas](#navegar-com-rotas-nomeadas)
  68 + - [Enviar dados para rotas nomeadas](#enviar-dados-para-rotas-nomeadas)
  69 + - [Links de Url dinâmicos](#links-de-url-dinâmicos)
  70 + - [Middleware](#middleware)
  71 + - [Change Theme](#change-theme)
  72 + - [Configurações Globais Opcionais](#configurações-globais-opcionais)
  73 +
  74 +
  75 +
  76 +
  77 +#### Você pode contribuir no projeto de várias formas:
  78 +- Ajudando a traduzir o README para outras linguagens.
  79 +- Adicionando mais documentação ao README (até o momento, nem metade das funcionalidades do Get foram documentadas).
  80 +- Fazendo artigos/vídeos ensinando a usar o Get (eles serão inseridos no README, e no futuro na nossa Wiki).
  81 +- Fazendo PR's (Pull-Requests) para código/testes.
  82 +- Incluindo novas funcionalidades.
  83 +
  84 +Qualquer contribuição é bem-vinda!
30 85
31 ## Como usar? 86 ## Como usar?
32 87
33 -Adicione esse pacote ao seu arquivo pubspec.yaml: 88 +<!-- - Flutter Master/Dev/Beta: version 2.0.x-dev
  89 +- Flutter Stable branch: version 2.0.x
  90 +(procure pela versão mais recente em pub.dev) -->
34 91
35 -```  
36 -dependencies:  
37 - get: ^1.17.3 // ^1.20.1-dev on beta/dev/master  
38 -```  
39 -  
40 -Importe ele se seu IDE não fizer isso de forma automática: 92 +Adicione Get ao seu arquivo pubspec.yaml
  93 +<!-- de acordo com a versão do flutter que você estiver usando -->
  94 +
  95 +Troque seu `MaterialApp()` por `GetMaterialApp()` e aproveite!
41 ```dart 96 ```dart
42 import 'package:get/get.dart'; 97 import 'package:get/get.dart';
  98 +
  99 +GetMaterialApp( // Before: MaterialApp(
  100 + home: MyHome(),
  101 +)
43 ``` 102 ```
44 -Adicione GetKey ao seu MaterialApp e aproveite!  
45 -```dart  
46 -MaterialApp(  
47 - navigatorKey: Get.key,  
48 - home: MyHome(),  
49 - )  
50 -```  
51 -### Navegando sem rotas nomeadas  
52 -Para ir para outra tela:  
53 103
  104 +## Navegação sem rotas nomeadas
  105 +
  106 +Para navegar para uma próxima tela:
54 ```dart 107 ```dart
55 -Get.to(NextScreen()); 108 +Get.to(ProximaTela());
56 ``` 109 ```
57 110
58 -Para voltar para a tela anterior  
59 - 111 +Para retornar para a tela anterior:
60 ```dart 112 ```dart
61 Get.back(); 113 Get.back();
62 ``` 114 ```
63 115
64 -Para ir para a próxima tela e tirar a rota atual da stack de navegação (uso comum em SplashScreens, telas de cadastros e qualquer outra tela que você não deseja exibir quando clicar em voltar)  
65 - 116 +Para ir para a próxima tela e NÃO deixar opção para voltar para a tela anterior (bom para SplashScreens, telas de login e etc.):
66 ```dart 117 ```dart
67 -Get.off(NextScreen()); 118 +Get.off(ProximaTela());
68 ``` 119 ```
69 120
70 -Ir para a próxima tela e tirar todas as telas anteriores da stack de navegação (geralmente usado em carrinhos de compras, provas, enquetes e etc) 121 +Para ir para a próxima tela e cancelar todas as rotas anteriores (útil em telas de carrinho, votações ou testes):
71 122
72 ```dart 123 ```dart
73 -Get.offAll(NextScreen()); 124 +Get.offAll(ProximaTela());
74 ``` 125 ```
75 126
76 -Para navegar para uma rota e receber ou atualizar dados assim que voltar dela: 127 +Para navegar para a próxima rota, e receber ou atualizar dados assim que retornar da rota:
77 ```dart 128 ```dart
78 -var data = await Get.to(Payment()); 129 +var dados = await Get.to(Pagamento());
79 ``` 130 ```
80 -Na próxima tela, envie algum dado para a screen anterior ao voltar (pode ser qualquer coisa, Strings, int, Maps, até instâncias de classes, você pode tudo): 131 +Na outra tela, envie os dados para a rota anterior:
81 132
82 ```dart 133 ```dart
83 -Get.back(result: 'sucess'); 134 +Get.back(result: 'sucesso');
84 ``` 135 ```
85 -E você pode usar o dado recebido assim: 136 +E use-os:
86 137
87 -ex:  
88 ```dart 138 ```dart
89 -if(data == 'sucess') madeAnything(); 139 +if (dados == 'sucesso') fazerQualquerCoisa();
90 ``` 140 ```
91 141
92 -Você não quer aprender nossa sintaxe?  
93 -Basta alterar o Navigator (maiúsculo) para navigator (minúsculo) e você terá todas as funções da navegação padrão, sem precisar usar o contexto  
94 -Exemplo: 142 +Não quer aprender nossa sintaxe?
  143 +Apenas mude o `Navigator` (letra maiúscula) para `navigator` (letra minúscula), e você terá todas as funcionalidades de navegação padrão, sem precisar usar `context`
95 144
  145 +Exemplo:
96 ```dart 146 ```dart
97 -  
98 -// Navegação padrão 147 +// Navigator padrão do Flutter
99 Navigator.of(context).push( 148 Navigator.of(context).push(
100 - context,  
101 - MaterialPageRoute(  
102 - builder: (BuildContext context) {  
103 - return HomePage();  
104 - },  
105 - ),  
106 - );  
107 -  
108 -// Usando Get com a sintaxe do Flutter 149 + context,
  150 + MaterialPageRoute(
  151 + builder: (BuildContext context) {
  152 + return HomePage();
  153 + },
  154 + ),
  155 +);
  156 +
  157 +// Get usando a sintaxe Flutter sem precisar do context
109 navigator.push( 158 navigator.push(
110 - MaterialPageRoute(  
111 - builder: (_) {  
112 - return HomePage();  
113 - },  
114 - ),  
115 - );  
116 -  
117 -// Usando a sintaxe do Get (Muito melhor, mas você pode discordar disso) 159 + MaterialPageRoute(
  160 + builder: (_) {
  161 + return HomePage();
  162 + },
  163 + ),
  164 +);
  165 +
  166 +// Sintaxe do Get (é bem melhor, mas você tem o direito de discordar)
118 Get.to(HomePage()); 167 Get.to(HomePage());
119 -  
120 -  
121 ``` 168 ```
122 169
123 ### SnackBars 170 ### SnackBars
124 171
125 -Para ter uma simples SnackBar com Flutter, você deve obter o contexto do Scaffold ou usar uma GlobalKey anexada ao seu Scaffold, 172 +Para ter um `SnackBar` simples no Flutter, você precisa do `context` do Scaffold, ou uma `GlobalKey` atrelada ao seu Scaffold.
126 ```dart 173 ```dart
127 final snackBar = SnackBar( 174 final snackBar = SnackBar(
128 - content: Text('Oi!'),  
129 - action: SnackBarAction(  
130 - label: 'Eu sou uma velha e feia snackbar :(',  
131 - onPressed: (){}  
132 - ),  
133 - // Find the Scaffold in the widget tree and use  
134 - // it to show a SnackBar.  
135 - Scaffold.of(context).showSnackBar(snackBar); 175 + content: Text('Olá!'),
  176 + action: SnackBarAction(
  177 + label: 'Eu sou uma SnackBar velha e feia :(',
  178 + onPressed: (){}
  179 + ),
  180 +);
  181 +// Encontra o Scaffold na árvore de Widgets e
  182 +// o usa para mostrar o SnackBar
  183 +Scaffold.of(context).showSnackBar(snackBar);
136 ``` 184 ```
137 185
138 -Já com o Get:  
139 - 186 +Com o Get:
140 ```dart 187 ```dart
141 -Get.snackbar('Oi', 'Eu sou uma snackbar bonita e moderna'); 188 +Get.snackbar('Olá', 'eu sou uma SnackBar moderna e linda!');
142 ``` 189 ```
143 190
144 -Com o Get, tudo o que você precisa fazer é chamar o Get.snackbar de qualquer lugar no seu código ou personalizá-lo como quiser! 191 +Com Get, tudo que você precisa fazer é chamar `Get.snackbar()` de qualquer lugar no seu código, e/ou customizá-lo da forma que quiser!
145 192
146 ```dart 193 ```dart
147 - Get.snackbar(  
148 - "Hey i'm a Get SnackBar!", // title  
149 - "It's unbelievable! I'm using SnackBar without context, without boilerplate, without Scaffold, it is something truly amazing!", // message  
150 - icon: Icon(Icons.alarm),  
151 - shouldIconPulse: true,  
152 - onTap:(){},  
153 - barBlur: 20,  
154 - isDismissible: true,  
155 - duration: Duration(seconds: 3),  
156 - );  
157 -  
158 -  
159 - ////////// TODOS RECURSOS ////////// 194 +Get.snackbar(
  195 + "Ei, eu sou uma SnackBar Get!", // título
  196 + "É inacreditável! Eu estou usando uma SnackBar sem context, sem boilerplate, sem Scaffold!", // mensagem
  197 + icon: Icon(Icons.alarm),
  198 + shouldIconPulse: true,
  199 + onTap:(){},
  200 + barBlur: 20,
  201 + isDismissible: true,
  202 + duration: Duration(seconds: 3),
  203 +);
  204 +
  205 +
  206 + ////////// TODOS OS RECURSOS //////////
160 // Color colorText, 207 // Color colorText,
161 // Duration duration, 208 // Duration duration,
162 // SnackPosition snackPosition, 209 // SnackPosition snackPosition,
163 // Widget titleText, 210 // Widget titleText,
164 // Widget messageText, 211 // Widget messageText,
  212 + // bool instantInit,
165 // Widget icon, 213 // Widget icon,
166 // bool shouldIconPulse, 214 // bool shouldIconPulse,
167 // double maxWidth, 215 // double maxWidth,
@@ -191,214 +239,710 @@ Com o Get, tudo o que você precisa fazer é chamar o Get.snackbar de qualquer l @@ -191,214 +239,710 @@ Com o Get, tudo o que você precisa fazer é chamar o Get.snackbar de qualquer l
191 // Form userInputForm 239 // Form userInputForm
192 /////////////////////////////////// 240 ///////////////////////////////////
193 ``` 241 ```
194 -Após a recusa de um aplicativo na AppleStore por usar a snackbar padrão que não combina nada com as Human Guidelines da Apple, resolvi criar a Get.snackbar, mas se você prefere a snackbar padrão, ou não desenvolve para iOS, você pode usar a API de baixo nível `GetBar().show();` que permite por exemplo, excluir a mensagem (Get.snackbar tem título e mensagem obrigatórios).  
195 -  
196 -### Caixas de dialogos 242 +Se você prefere a SnackBar tradicional, ou quer customizar por completo, como por exemplo fazer ele ter uma só linha (`Get.snackbar` tem os parâmetros `title` e `message` obrigatórios), você pode usar `Get.rawSnackbar();` que fornece a API bruta na qual `Get.snackbar` foi contruído.
197 243
198 -Para abrir uma caixa de diálogo: 244 +### Dialogs
199 245
  246 +Para abrir um dialog:
200 ```dart 247 ```dart
201 -Get.dialog(YourDialogWidget()); 248 +Get.dialog(SeuWidgetDialog());
202 ``` 249 ```
203 250
204 -Para abrir o dialogo padrão do Get:  
205 - 251 +Para abrir um dialog padrão:
206 ```dart 252 ```dart
207 - Get.defaultDialog(  
208 - title: "My Title",  
209 - content: Text("Hi, it's my dialog"),  
210 - confirm: FlatButton(  
211 - child: Text("Ok"),  
212 - onPressed: () => print("OK pressed"),  
213 - ),  
214 - cancel: FlatButton(  
215 - child: Text("Cancel"),  
216 - onPressed: () => Get.back(),  
217 - )); 253 +Get.defaultDialog(
  254 + onConfirm: () => print("Ok"),
  255 + middleText: "Dialog made in 3 lines of code",
  256 +);
218 ``` 257 ```
  258 +Você também pode usar `Get.generalDialog` em vez de `showGeneralDialog`.
  259 +
  260 +Para todos os outros Widgets do tipo dialog do Flutter, incluindo os do Cupertino, você pode usar `Get.overlayContext` em vez do `context`, e abrir em qualquer lugar do seu código.
  261 +
  262 +Para widgets que não usam `overlayContext`, você pode usar `Get.context`. Esses dois contextos vão funcionar em 99% dos casos para substituir o context da sua UI, exceto em casos onde o `inheritedWidget` é usado sem a navigation context.
219 263
220 ### BottomSheets 264 ### BottomSheets
221 -Get.bottomSheet é como showModalBottomSheet, mas não precisa de context. 265 +`Get.bottomSheet()` é tipo o `showModalBottomSheet()`, mas não precisa do context.
222 266
223 ```dart 267 ```dart
224 Get.bottomSheet( 268 Get.bottomSheet(
225 - builder: (_){  
226 - return Container(  
227 - child: Wrap(  
228 - children: <Widget>[  
229 - ListTile(  
230 - leading: Icon(Icons.music_note),  
231 - title: Text('Music'),  
232 - onTap: () => {}  
233 - ),  
234 - ListTile(  
235 - leading: Icon(Icons.videocam),  
236 - title: Text('Video'),  
237 - onTap: () => {},  
238 - ),  
239 - ],  
240 - ),  
241 - );  
242 - } 269 + Container(
  270 + child: Wrap(
  271 + children: <Widget>[
  272 + ListTile(
  273 + leading: Icon(Icons.music_note),
  274 + title: Text('Música'),
  275 + onTap: () => {}
  276 + ),
  277 + ListTile(
  278 + leading: Icon(Icons.videocam),
  279 + title: Text('Vídeo'),
  280 + onTap: () => {},
  281 + ),
  282 + ],
  283 + ),
  284 + ),
  285 +);
  286 +```
  287 +
  288 +## Gerenciador de estado simples
  289 +Há atualmente vários gerenciadores de estados para o Flutter. Porém, a maioria deles envolve usar `ChangeNotifier` para atualizar os widgets e isso é uma abordagem muito ruim no quesito performance em aplicações de médio ou grande porte. Você pode checar na documentação oficial do Flutter que o [`ChangeNotifier` deveria ser usado com um ou no máximo dois listeners](https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html), fazendo-o praticamente inutilizável em qualquer aplicação média ou grande. Outros gerenciadores de estado são bons, mas tem suas nuances. BLoC é bem seguro e eficiente, mas é muito complexo (especialmente para iniciantes), o que impediu pessoas de desenvolverem com Flutter. MobX é mais fácil que o BLoc e é reativo, quase perfeito eu diria, mas você precisa usar um code generator que, para aplicações de grande porte, reduz a produtividade (você terá que beber vários cafés até que seu código esteja pronto denovo depois de um `flutter clean`, o que não é culpa do MobX, na verdade o code generator que é muito lento!). Provider usa o `InheritedWidget` para entregar o mesmo listener, como uma forma de solucionar o problema reportado acima com o ChangeNotifier, o que indica que qualquer acesso ao ChangeNotifier dele tem que ser dentro da árvore de widgets por causa do `context` necessário para acessar o Inherited.
  290 +
  291 +Get não é melhor ou pior que nenhum gerenciador de estado, mas você deveria analisar esses pontos tanto quanto os argumentos abaixo para escolher entre usar Get na sua forma pura, ou usando-o em conjunto com outro gerenciador de estado. Definitivamente, Get não é o inimigo de nenhum gerenciador, porque Get é um microframework, não apenas um gerenciador, e pode ser usado tanto sozinho quanto em conjunto com eles.
  292 +
  293 +Get tem um gerenciador de estado que é extremamente leve e fácil (escrito em apenas 95 linha de código), que não usa ChangeNotifier, vai atender a necessidade especialmente daqueles novos no Flutter, e não vai causar problemas em aplicações de grande porte.
  294 +
  295 +**Que melhoras na performance o Get traz?**
  296 +
  297 +1. Atualiza somente o widget necessário.
  298 +
  299 +2. Não usa o `ChangeNotifier`, é o gerenciador de estado que utiliza menos memória (próximo de 0mb até agora).
  300 +
  301 +3. Esqueça StatefulWidget's! Com Get você nunca mais vai precisar deles. Com outros gerenciadores de estado, você provavelmente precisa usar um StatefulWidget para pegar a instância do seu Provider, BLoc, MobX controller, etc. Mas já parou para pensar que seu AppBar, seu Scaffold e a maioria dos widgets que estão na sua classe são stateless? Então porque salvar o estado de uma classe inteira, se você pode salvar somente o estado de um widget stateful? Get resolve isso também. Crie uma classe Stateless, faça tudo stateless. Se você precisar atualizar um único componente, envolva ele com o `GetBuilder`, e seu estado será mantido.
  302 +
  303 +4. Organize seu projeto de verdade! Controllers não devem ficar na sua UI, coloque seus `TextEditController`, ou qualquer controller que você usa dentro da classe Controller.
  304 +
  305 +5. Você precisa acionar um evento para atualizar um widget assim que ele é renderizado? GetBuilder tem a propriedade `initState()` assim como um StatefulWidget, e você pode acionar eventos a partir do seu controller, diretamente de lá. Sem mais de eventos serem colocados no initState.
  306 +
  307 +6. Você precisa acionar uma ação como fechar Streams, timers, etc? GetBuilder também tem a propriedade `dispose()`, onde você pode acionar eventos assim que o widget é destruído.
  308 +
  309 +7. Use `Stream`s somente se necessário. Você pode usar seus StreamControllers dentro do seu controller normalmente, e usar `StreamBuilder` normalmente também, mas lembre-se, um Stream consume uma memória razoável, programação reativa é linda, mas você não abuse. 30 Streams abertos simultaneamente podem ser ainda piores que o `ChangeNotifier` (e olha que o ChangeNotifier é bem ruim)
  310 +
  311 +8. Atualizar widgets sem gastar memória com isso. Get guarda somente a "ID do criador" do GetBuilder, e atualiza esse GetBuilder quando necessário. O consumo de memória do ID do GetBuilder é muito baixo mesmo para milhares de GetBuilders. Quando você cria um novo GetBuilder, na verdade você está compartilhando o estado do GetBuilder quem tem um ID do creator. Um novo estado não é criado para cada GetBuilder, o que reduz MUITO o consumo de memória RAM em aplicações grandes. Basicamente sua aplicação vai ser toda stateless, e os poucos widgets que serão Stateful (dentro do GetBuilder) vão ter um estado único, e assim atualizar um deles vai atualizar todos eles. O estado é um só.
  312 +
  313 +9. Get é onisciente e na maioria dos casos sabe o momento exato de tirar um controller da memória. Você não precisa se preocupar com quando descartar o controller, Get sabe o melhor momento para fazer isso.
  314 +
  315 +Vamos analisar o seguite exemplo:
  316 +
  317 +`Class A => Class B (ControllerX) => Class C (ControllerX)`
  318 +
  319 +* Na classe A o controller não está ainda na memória, porque você ainda não o usou (Get carrega só quando precisa).
  320 +
  321 +* Na classe B você usou o controller, e ele entrou na memória.
  322 +
  323 +* Na classe C você usou o mesmo controller da classe B, então o Get vai compartilhar o estado do controller B com o controller C, e o mesmo controller ainda estará na memória.
  324 +
  325 +* Se você fechar a classe C e classe B, Get vai tirar o controller X da memória automaticamente e liberar recursos, porque a classe A não está usando o controller.
  326 +
  327 +* Se você navegar para a Classe B denovo, o controller X vai entrar na memória denovo.
  328 +
  329 +* Se em vez de ir para a classe C você voltar para a classe A, Get vai tirar o controller da memória do mesmo jeito.
  330 +
  331 +* Se a classe C não usar o controller, e você tirar a classe B da memória, nenhuma classe estaria usando o controller X, e novamente o controller seria descartado.
  332 +
  333 +**Nota**: A única exceção que pode atrapalhar o Get, é se
  334 +Você remover classe B da rota de forma inesperada, e tentasse usar o controller na classe C. Nesse caso, o ID do creator do controller que estava em B seria deletado, e o Get foi programado para remover da memória todo controller que não tem nenhum ID de creator. Se é sua intenção fazer isso, adicione a config `autoRemove: false` no GetBuilder da classe B, e use `adoptID = true;` no GetBuilder da classe C.
  335 +
  336 +### Uso do gerenciador de estado simples
  337 +
  338 +```dart
  339 +// Crie a classe Controller e entenda ela do GetController
  340 +class Controller extends GetController {
  341 + int counter = 0;
  342 + void increment() {
  343 + counter++;
  344 + update(this); // use update(this) para atualizar a variável counter na UI quando increment for chamado
  345 + }
  346 +}
  347 +// Na sua classe Stateless/Stateful, use o GetBuilder para atualizar o texto quando a função increment for chamada
  348 +GetBuilder<Controller>(
  349 + init: Controller(), // INICIE O CONTROLLER SOMENTE NA PRIMEIRA VEZ
  350 + builder: (controller) => Text(
  351 + '${controller.counter}',
  352 + ),
  353 +),
  354 +// Inicialize seu controller somente uma vez. Na segunda vez que você for usar GetBuilder para o mesmo controller, não Inicialize denovo. Seu controller será automaticamente removido da memória. Você não precisa se preocupar com isso, Get vai fazer isso automaticamente, apenas tenha certeza que você não vai inicializar o mesmo controller duas vezes.
  355 +```
  356 +**Feito!**
  357 +
  358 +Você já aprendeu como gerenciar estados com o Get.
  359 +
  360 +Nota: Você talvez queira uma maior organização, e não querer usar a propriedade `init`. Para isso, você pode criar uma classe e extendê-la da classe `Bindings`, e nela mencionar os controllers que serão criados dentro daquela rota. Controllers não serão criados naquele momento exato, muito pelo contrário, isso é apenas uma declaração, para que na primeira vez que vc use um Controller, Get vai saber onde procurar. Get vai continuar no formato "lazyLoad" (carrega somente quando necessário) e vai continuar descartando os Controllers quando eles não forem mais necessários. Veja pub.dev example para ver como funciona.
  361 +
  362 +Se você navegar por várias rotas e precisa de algum dado que estava em um outro controller previamente utilizado, você só precisa utilizar o GetBuilder novamente (sem o init):
  363 +
  364 +```dart
  365 +class OutraClasse extends StatelessWidget {
  366 + @override
  367 + Widget build(BuildContext context) {
  368 + return Scaffold(
  369 + body: Center(
  370 + child: GetBuilder<Controller>(
  371 + builder: (s) => Text('${s.counter}'),
  372 + ),
  373 + ),
243 ); 374 );
  375 + }
  376 +}
244 ``` 377 ```
245 -### Configurações Globais  
246 -Você pode criar configurações globais para o Get. Basta adicionar Get.config ao seu código antes de enviar qualquer rota. (Se não souber onde colocar, coloque dentro da função main()) 378 +
  379 +Se você precisa utilizar seu controller em vários outros lugares, e fora do GetBuilder, apenas crie um getter no seu controller que você consegue ele facilmente (ou use `Get.find<Controller>()` )
247 380
248 ```dart 381 ```dart
249 -Get.config(  
250 - enableLog = true,  
251 - defaultPopGesture = true,  
252 - defaultTransition = Transitions.cupertino} 382 +class Controller extends GetController {
  383 +
  384 + /// Você não precisa disso. Eu recomendo usar isso apenas
  385 + /// porque a sintaxe é mais fácil.
  386 + /// com o método estático: Controller.to.counter();
  387 + /// sem o método estático: Get.find<Controller>();
  388 + /// Não há diferença em performance, nem efeito colateral por usar esse sintaxe. Só uma não precisa da tipage, e a outra forma a IDE vai autocompletar.
  389 + static Controller get to => Get.find(); // adicione esta linha
  390 +
  391 + int counter = 0;
  392 + void increment() {
  393 + counter++;
  394 + update(this);
  395 + }
  396 +}
  397 +```
  398 +E então você pode acessar seu controller diretamente, desse jeito:
  399 +```dart
  400 +FloatingActionButton(
  401 + onPressed:(){
  402 + Controller.to.increment(),
  403 + } // Isso é incrivelmente simples!
  404 + child: Text("${Controller.to.counter}"),
  405 +),
  406 +```
  407 +Quando você pressionar o FloatingActionButton, todos os widgets que estão escutando a variável `counter` serão atualizados automaticamente.
  408 +
  409 +#### Sem StatefulWidget;
  410 +Usar StatefulWidget's significa guardar o estado de telas inteiras desnecessariamente, mesmo porque se você precisa recarregar minimamente algum widget, você vai incorporá-lo num Consumer/Observer/BlocProvider/GetBuilder/GetX/Obx, que vai ser outro StatefulWidget.
  411 +A classe StatefulWidget é maior que a classe StatelessWidget, o que vai alocar mais memória, e isso pode não fazer uma diferença significativa com uma ou duas classes, mas com certeza fará quando você tiver 100 delas!
  412 +
  413 +A não ser que você precise usar um mixin, como o `TickerProviderStateMixin`, será totalmente desnecessário usar um StatefulWidget com o Get.
  414 +
  415 +Você pode chamar todos os métodos de um StatefulWidget diretamente de um GetBuilder.
  416 +Se você precisa chamar o método `initState()` ou `dispose()` por exemplo, é possível chamá-los diretamente:
  417 +```dart
  418 +GetBuilder<Controller>(
  419 + initState: (_) => Controller.to.fetchApi(),
  420 + dispose: (_) => Controller.to.closeStreams(),
  421 + builder: (s) => Text('${s.username}'),
  422 +),
  423 +```
  424 +Uma abordagem muito melhor que isso é usar os métodos `onInit()` e `onClose()` diretamente do seu controller.
  425 +
  426 +```dart
  427 +@override
  428 +void onInit() {
  429 + fetchApi();
  430 + super.onInit();
  431 +}
  432 +```
  433 +* Nota: Se você quiser executar um método no momento que o controller é chamado pela primeira vez, você NÃO precisa usar construtores para isso, na verdade, usando um package que é focado em performance como o Get, isso chega no limite de má prática, porque se desvia da lógica de que os controllers são criados ou alocados (Se você criar uma instância desse controller, o construtor vai ser chamado imediatamente, e ele será populado antes de ser usado, ou seja, você está alocando memória e não está utilizando, o que fere os princípios desse package). Os métodos `onInit()` e `onClose()` foram criados para isso, eles serão chamados quando o controller é criado, ou usados pela primeira vez, dependendo de como você está utilizando o Get (lazyPut ou não). Se quiser, por exemplo, fazer uma chamada para sua API para popular dados, você pode esquecer do estilo antigo de usar `initState()/dispose()`, apenas comece sua chamada para a api no `onInit`, e apenas se você precisar executar algum comando como fechar stream, use o `onClose()`.
  434 +
  435 +O propósito desse package é precisamente te dar uma solução completa para navegação de rotas, gerenciamente de dependências e estados, usando o mínimo possível de dependências, com um alto grau de desacoplamento. Get envolve em todas as APIs de baixo e alto nível dentro de si mesmo, para ter certeza que você irá trabalhar com o mínimo possível de acoplamento.
  436 +
  437 +Nós centralizamos tudo em um único package. Dessa forma, você pode colocar somente widgets na sua view, e o controller pode ter só lógica de negócio, sem depender de nenhum elemento da View. Isso fornece um ambiente de trabalho muito mais limpo, para que parte do seu time possa trabalhar apenas com os widgets, sem se preocupar sobre enviar dados para o controller, e outra parte se preocupe apenas com a lógica de negócio, sem depender de nenhum elemento da view.
  438 +
  439 +Então, para simplificar isso:
  440 +
  441 +Você não precisa chamar métodos no `initState()` e enviá-los para seu controller via parâmetros, nem precisa do construtor do controller pra isso, você possui o método `onInit()` que é chamado no momento certo para você inicializar seus services.
  442 +
  443 +Você não precisa chamar o método `dispose()`, você tem o método `onClose()` que vai ser chamado no momento exato quando seu controller não for mais necessário e será removido da memória. Dessa forma, você pode deixar a view somente para os widgets, e o controller só para as regras de negócio.
  444 +
  445 +Não chame o método `dispose()` dentro do GetController, não vai fazer nada. Lembre-se que o controller não é um widget, você não deveria usar o dispose lá, e esse método será automaticamente e inteligentemente removido da memória pelo Get. Se você usou algum stream no controller e quer fechá-lo, apenas insira o método para fechar os stream dentro do método `onClose()`.
  446 +
  447 +Exemplo:
  448 +```dart
  449 +class Controller extends GetController {
  450 + var user = StreamController<User>();
  451 + var name = StreamController<String>();
  452 +
  453 + /// fechar stream = método onClose(), não dispose().
  454 + @override
  455 + void onClose() {
  456 + user.close();
  457 + name.close();
  458 + super.onClose();
  459 + }
  460 +}
253 ``` 461 ```
  462 +Ciclo de vida do controller:
  463 +* `onInit()`: Onde ele é criado.
  464 +* `onClose()`: Onde ele é fechado para fazer mudanças em preparação para o método delete()
  465 +* deleted: Você não tem acesso a essa API porque ela está literalmente removendo o controller da memória. Está literalmente deletado, sem deixar rastros.
254 466
255 -## Gerenciador de instâncias descomplicado  
256 -Além de aumentar produtividade, muita gente usa Get para ter um aplicativo menor. Se você tem várias rotas e snackbars em seu aplicativo, ele provavelmente terá um código final maior que seu aplicativo + essa biblioteca  
257 -Se você já está usando o Get e deseja tornar seu projeto o mais enxuto possível, agora o Get possui um gerenciador de instancias simples que permite recuperar a mesma classe do seu Bloc ou Controller com apenas 1 linhas de código. 467 +##### Formas de uso:
  468 +
  469 +Você pode usar uma instância do Controller diretamente no `value` do GetBuilder
  470 +
  471 +```dart
  472 +GetBuilder<Controller>(
  473 + init: Controller(),
  474 + builder: (value) => Text(
  475 + '${value.counter}', //aqui
  476 + )
  477 +),
  478 +```
  479 +Você talvez também precise de uma instância do seu controller fora do GetBuilder, e você pode usar essas abordagens para conseguir isso:
  480 +
  481 +essa:
  482 +```dart
  483 +class Controller extends GetController {
  484 + static Controller get to => Get.find(); // criando um getter estático
  485 + [...]
  486 +}
  487 +// Na sua view/tela
  488 +GetBuilder<Controller>(
  489 + init: Controller(), // use somente uma vez por controller, não se esqueça
  490 + builder: (_) => Text(
  491 + '${Controller.to.counter}', //aqui
  492 + )
  493 +),
  494 +```
  495 +
  496 +ou essa:
  497 +```dart
  498 +class Controller extends GetController {
  499 + // sem nenhum método estático
  500 +[...]
  501 +}
  502 +// Numa classe stateful/stateless
  503 +GetBuilder<Controller>(
  504 + init: Controller(), // use somente uma vez por controller, não se esqueça
  505 + builder: (_) => Text(
  506 + '${Get.find<Controller>().counter}', //aqui
  507 + )
  508 +),
  509 +```
  510 +
  511 +* Você pode usar outras abordagens "menos regulares". Se você está utilizando outro gerenciador de dependências, como o get_it, modular, etc., e só quer entregar a instância do controller, pode fazer isso:
  512 +
  513 +```dart
  514 +Controller controller = Controller();
  515 +[...]
  516 +GetBuilder<Controller>(
  517 + init: controller, //aqui
  518 + builder: (_) => Text(
  519 + '${controller.counter}', // aqui
  520 + )
  521 +),
  522 +
  523 +```
  524 +
  525 +Essa abordagem não é recomendada, uma vez que você vai precisar descartar os controllers manualmente, fechar seus stream manualmente, e literalmente abandonar um dos grandes benefícios desse package, que é controle de memória inteligente. Mas se você confia no seu potencial, vai em frente!
  526 +
  527 +Se você quiser refinar o controle de atualização de widgets do GetBuilder, você pode assinalar a ele IDs únicas
  528 +```dart
  529 +GetBuilder<Controller>(
  530 + id: 'text'
  531 + init: Controller(), // use somente uma vez por controller, não se esqueça
  532 + builder: (_) => Text(
  533 + '${Get.find<Controller>().counter}', //aqui
  534 + )
  535 +),
  536 +```
  537 +E atualizá-los dessa forma:
  538 +```dart
  539 +update(this,['text']);
  540 +```
  541 +
  542 +Você também pode impor condições para o update acontecer:
  543 +```dart
  544 +update(this,['text'], counter < 10);
  545 +```
  546 +
  547 +GetX faz isso automaticamente e somente reconstrói o widget que usa a exata variável que foi alterada. Se você alterar o valor da variável para o mesmo valor que ela era anteriormente e isso não sugira uma mudança de estado, GetX não vai reconstruir esse widget, economizando memória e ciclos de CPU (Ex: 3 está sendo mostrado na tela, e você muda a variável para ter o valor 3 denovo. Na maioria dos gerenciadores de estado, isso vai causar uma reconstrução do widget, mas com o GetX o widget só vai reconstruir se de fato o estado mudou).
  548 +
  549 +GetBuilder é focado precisamente em múltiplos controles de estados. Imagine que você adicionou 30 produtos ao carrinho, você clica pra deletar um deles, e ao mesmo tempos a lista é atualizada, o preço é atualizado e o pequeno círculo mostrando a quantidade de produtos é atualizado. Esse tipo de abordagem faz o GetBuilder excelente, porque ele agupa estados e muda todos eles de uma vez sem nenhuma "lógica computacional" pra isso. GetBuilder foi criado com esse tipo de situação em mente, já que pra mudanças de estados simples, você pode simplesmente usar o `setState()`, e você não vai precisar de um gerenciador de estado para isso. Porém, há situações onde você quer somente que o widget onde uma certa variável mudou seja reconstruído, e isso é o que o GetX faz com uma maestria nunca vista antes.
  550 +
  551 +Dessa forma, se você quiser controlar individualmente, você pode assinalar ID's para isso, ou usar GetX. Isso é com você, apenas lembre-se que quando mais "widgets individuais" você tiver, mais a performance do GetX vai se sobressair. Mas o GetBuilder vai ser superior quando há multiplas mudanças de estado.
  552 +
  553 +Você pode usar os dois em qualquer situação, mas se quiser refinar a aplicação para a melhor performance possível, eu diria isso: se as suas variáveis são alteradas em momentos diferentes, use GetX, porque não tem competição para isso quando o widget é para reconstruir somente o que é necessário. Se você não precisa de IDs únicas, porque todas as suas variáveis serão alteradas quando você fazer uma ação, use GetBuilder, porque é um atualizador de estado em blocos simples, feito com apenas algumas linhas de código, para fazer justamente o que ele promete fazer: atualizar estado em blocos. Não há forma de comparar RAM, CPU, etc de um gerenciador de estado gigante com um simples StatefulWidget (como GetBuilder) que é atualizado quando você chama `update(this)`. Foi feito de uma forma simples, para ter o mínimo de lógica computacional, somente para cumprir um único papel e gastar o mínimo de recursos possível.
  554 +Se você quer um gerenciador de estados poderoso, você pode ir sem medo para o GetX. Ele não funciona com variáveis, mas sim fluxos. Tudo está em seus streams por baixo dos panos. Você pode usar `rxDart` em conjunto com ele, porque tudo é um stream, você pode ouvir o evento de cada "variável", porque tudo é um stream, é literalmente BLoc, só que mais fácil que MobX e sem code generators ou decorations.
  555 +
  556 +## Reactive State Manager - GetX
  557 +
  558 +Se você quer poder, Get té dá o mais avançado gerenciador de estado que você pode ter.
  559 +GetX foi construído 100% baseado em Stream, e te dá todo o poder de fogo que o BLoc te dá, com uma sintaxe mais fácil que a do MobX.
  560 +Sem decorations, você poder tornar qualquer coisa em um `Observable` com somete um `.obs`
  561 +
  562 +Performance máxima: Somando ao fato de ter um algoritmo inteligente para reconstrução mínima, Get usa comparadores para ter certeza que o estado mudou. Se você encontrar erros na sua aplicação, e enviar uma mudança de estado duplicada, Get vai ter certeza que sua aplicação não entre em colapso.
  563 +
  564 +O estado só muda se o valor mudar. Essa é a principal diferença entre Get, e usar o `Computed` do MobX. Quando juntar dois observables, se um deles é alterado, a escuta daquele observable vai mudar. Com Get, se você juntar duas variáveis (que na verdade é desnecessário), GetX(similar ao Observer) vai somente mudar se implicar numa mudança real de estado. Exemplo:
  565 +
  566 +```dart
  567 +final count1 = 0.obs;
  568 +final count2 = 0.obs;
  569 +int get sum => count1.value + count2.value;
  570 +```
  571 +
  572 +```dart
  573 +GetX<Controller>(
  574 + builder: (_) {
  575 + print("count 1 foi reconstruído");
  576 + return Text('${_.count1.value}');
  577 + },
  578 +),
  579 +GetX<Controller>(
  580 + builder: (_) {
  581 + print("count 2 foi reconstruído");
  582 + return Text('${_.count2.value}');
  583 + },
  584 +),
  585 +GetX<Controller>(
  586 + builder: (_) {
  587 + print("sum foi reconstruído");
  588 + return Text('${_.sum}');
  589 + },
  590 +),
  591 +```
  592 +Se nós incrementarmos o número do `count1`, somente `count1` e `sum` serão reconstruídos, porque `count1` agora tem um valor de 1, e 1 + 0 = 1, alterando o valor do `sum`.
  593 +
  594 +Se nós mudarmos `count2`, somente `count2` e `sum` serão reconstruídos, porque o valor do 2 mudou, e o resultado da variável `sum` é agora 2.
  595 +
  596 +Se definirmos o valor de `count1` para 1, nenhum widget será reconstruído, porque o valor já era 1.
  597 +
  598 +Se definirmos o valor de `count1` para 1 denovo, e definirmos o valor de `count2` para 2, então somente o `count2`e o `sum` vão ser reconstruídos, simplesmente porque o GetX não somente altera o que for necessário, ele também evita eventos duplicados.
  599 +
  600 +Somando a isso, Get provê um controle de estado refinado. Você pode adicionar uma condição a um evento (como adicionar um objeto a uma lista).
  601 +
  602 +```dart
  603 +list.addIf(item < limit, item);
  604 +```
  605 +
  606 +Sem decorations, sem code generator, sem complicações, GetX vai mudar a forma que você controla seus estados no Flutter, e isso não é uma promessa, isso é uma certeza!
  607 +
  608 +Sabe o app de contador do Flutter? Sua classe Controller pode ficar assim:
  609 +```dart
  610 +class CountController extends RxController {
  611 + final count = 0.obs;
  612 +}
  613 +```
  614 +E com um simples:
  615 +```dart
  616 +controller.count.value++
  617 +```
  618 +
  619 +Você pode atualizar a variável counter na sua UI, independente de onde esteja sendo armazenada.
  620 +
  621 +Você pode transformar qualquer coisa em obs:
  622 +```dart
  623 +class RxUsuario {
  624 + final nome = "Camila".obs;
  625 + final idade = 18.obs;
  626 +}
  627 +
  628 +class Usuario {
  629 + Usuario({String nome, int idade});
  630 + final rx = RxUsuario();
  631 +
  632 + String get nome => rx.nome.value;
  633 + set nome(String value) => rx.nome.value = value;
  634 +
  635 + int get idade => rx.idade.value;
  636 + set idade(int value) => rx.idade.value = value;
  637 +}
  638 +```
  639 +
  640 +```dart
  641 +
  642 +void main() {
  643 + final usuario = Usuario();
  644 + print(usuario.nome);
  645 + usuario.idade = 23;
  646 + usuario.rx.idade.listen((int idade) => print(idade));
  647 + usuario.idade = 24;
  648 + usuario.idade = 25;
  649 +}
  650 +___________
  651 +saída:
  652 +Camila
  653 +23
  654 +24
  655 +25
  656 +```
  657 +
  658 +Trabalhar com `Lists` usando Get é algo muito agradável. Elas são completamente observáveis assim como os objetos dentro dela. Dessa forma, se você adicionar uma valor a lista, ela vai automaticamente reconstruir os widgets que a usam.
  659 +
  660 +Você também não precisa usar `.value` com listas, a api dart nos permitiu remover isso. Infelizmente tipos primitivos como String e int não podem ser extendidos, fazend o uso de `.value` obrigatório, mas isso não será um problema se você usar getters e setters para esses.
  661 +```dart
  662 +final list = List<Usuario>().obs;
  663 +
  664 +ListView.builder (
  665 +itemCount: list.lenght
  666 +)
  667 +```
  668 +
  669 +Você não precisa trabalhar com sets se não quiser. Você pode usar as APIs `assign` e `assignAll`
  670 +
  671 +A api `assign` vai limpar sua lista e adicionar um único objeto que você quer.
  672 +
  673 +A api `assignAll` vai limpar sua lista e vai adicionar objetos `Iterable` que você precisa.
  674 +
  675 +Nós poderíamos remover a obrigação de usar o value em String e int com uma simples decoration e code generator, mas o propósito desse package é precisamente não precisar de nenhuma dependência externa. É para oferecer um ambiente pronto para programar, envolvendo os essenciais (gerenciamento de rotas, dependências e estados), numa forma simples, leve e performática sem precisar de packages externos. Você pode literalmente adicionar 3 letras e um ':' no seu pubspec.yaml e começar a programar. Todas as soluções incluídas por padrão, miram em facilidade, produtividade e performance.
  676 +
  677 +O peso total desse package é menor que o de um único gerenciador de estado, mesmo sendo uma solução completa, e isso é o que você precisa entender.
  678 +
  679 +Se você está incomodado com o `.value`, e gosta de code generator, MobX é uma excelente alternativa, e você pode usá-lo em conjunto com o Get. Para aqueles que querem adicionar uma única dependência no pubspec.yaml e começar a programar sem se preocupar sobre a versão de um package sendo incompatível com outra, ou se o erro de uma atualização do estado está vindo do gerenciador de estado ou da dependência, ou ainda, não quer se preocupar com a disponibilidade de controllers, prefere literalmente "só programar", Get é perfeito.
  680 +
  681 +Agora se você não tem problemas com o code generator do MobX, ou não vê problema no boilerplate do BLoc, você pode simplesmente usar o Get para rotas, e esquecer que nele existe um gerenciador de estado. Get nasceu da necessidade, minha empresa tinha um projeto com mais de 90 controllers e o code generator simplesmente levava mais de 30 minutos para completar suas tarefas depois de um `flutter clean` numa máquina razoavelmente boa, se o seu projeto tem 5, 10, 15 controllers, qualquer gerenciador de estado vai ter satisfazer.
  682 +
  683 +Se você tem um projeto absurdamente grande, e code generator é um problema para você, então você foi presenteado com essa solução que é o Get.
  684 +
  685 +Obviamente, se alguém quiser contribuir para o projeto e criar um code generator, or algo similar, eu vou linkar no README como uma alternativa, minha necessidade não é a necessidade de todos os devs, mas por agora eu digo: há boas soluções que já fazem isso, como MobX.
  686 +
  687 +Tipagem no Get usando Bindings é desnecessário. Você pode usar o widget `Obx()` em vez do GetX, e ele só recebe a função anônima que cria o widget.
  688 +
  689 +## Gerenciamento de dependências simples
  690 +
  691 +* Nota: Se você está usando o gerenciado de estado do Get, você não precisa se preocupar com isso, só leia a documentação, mas dê uma atenção a api `Bindings`, que vai fazer tudo isso automaticamente para você.
  692 +
  693 +Já está usando o Get e quer fazer seu projeto o melhor possível? Get tem um gerenciador de dependência simples e poderoso que permite você pegar a mesma classe que seu Bloc ou Controller com apenas uma linha de código, sem Provider context, sem inheritedWidget:
258 694
259 ```dart 695 ```dart
260 Controller controller = Get.put(Controller()); // Em vez de Controller controller = Controller(); 696 Controller controller = Get.put(Controller()); // Em vez de Controller controller = Controller();
261 ``` 697 ```
262 -Em vez de instanciar seu controlador dentro da classe que você está usando, use o metodo put para que o Get pegue sua instância e disponibilize por todo o seu aplicativo.  
263 -Então você pode usar seu controlador (ou classe Bloc) normalmente.  
264 698
  699 +Em vez de instanciar sua classe dentro da classe que você está usando, você está instanciando ele dentro da instância do Get, que vai fazer ele ficar disponível por todo o App
  700 +
  701 +Para que então você possa usar seu controller (ou uma classe Bloc) normalmente
265 ```dart 702 ```dart
266 -controller.fetchApi();// Rather Controller controller = Controller(); 703 +controller.fetchApi();
267 ``` 704 ```
268 705
269 -Agora, imagine que você navegou por inúmeras rotas e precisa de dados que foram deixados para trás em seu controlador; você precisaria de um gerenciador de estado combinado com o Provider ou Get_it, correto? Não com Get. Você só precisa pedir ao Get para "procurar" pelo seu controlador, você não precisa de nenhuma dependência adicional para isso: 706 +Agora, imagine que você navegou por inúmeras rotas e precisa de dados que foram deixados para trás em seu controlador. Você precisaria de um gerenciador de estado combinado com o Provider ou Get_it, correto? Não com Get. Você só precisa pedir ao Get para "procurar" pelo seu controlador, você não precisa de nenhuma dependência adicional para isso:
270 707
271 ```dart 708 ```dart
272 Controller controller = Get.find(); 709 Controller controller = Get.find();
273 -// Sim, parece Magia, o Get irá descobrir qual é seu controller, e irá te entregar. Você pode ter 1 milhão de controllers instanciados, o Get sempre te entregará o controller correto. Apenas se lembre de Tipar seu controller, final controller = Get.find(); por exemplo, não irá funcionar. 710 +// Sim, parece Magia, o Get irá descobrir qual é seu controller, e irá te entregar.
  711 +// Você pode ter 1 milhão de controllers instanciados, o Get sempre te entregará o controller correto.
  712 +// Apenas se lembre de Tipar seu controller, final controller = Get.find(); por exemplo, não irá funcionar.
274 ``` 713 ```
275 -E então você poderá recuperar os dados do seu controlador obtidos lá:  
276 714
  715 +E então você será capaz de recuperar os dados do seu controller que foram obtidos anteriormente:
277 ```dart 716 ```dart
278 Text(controller.textFromApi); 717 Text(controller.textFromApi);
279 ``` 718 ```
  719 +Procurando por `lazyLoading`?(carregar somente quando for usar) Você pode declarar todos os seus controllers, e eles só vão ser inicializados e chamados quando alguém precisar. Você pode fazer isso
  720 +```dart
  721 +Get.lazyPut<Service>(()=> ApiMock());
  722 +/// ApiMock só será chamado quando alguém usar o Get.find<Service> pela primeira vez
  723 +```
  724 +
  725 +Para remover a instância do Get:
  726 +```dart
  727 +Get.delete<Controller>();
  728 +```
  729 +
  730 +## Bindings
  731 +Um dos grandes diferenciais desse package, talvez, seja a possibilidade de integração total com rotas, gerenciador de estado e gerenciador de dependências.
  732 +
  733 +Quando uma rota é removida da stack, todos os controllers, variáveis e instâncias de objetos relacionados com ela são removidos da memória. Se você está usando streams ou timer, eles serão fechados automaticamente, e você não precisa se preocupar com nada disso.
280 734
281 -Quer liberar recursos? Para remover uma instância do Get, apenas delete ela: 735 +Na versão 2.10 Get implementou completamente a API Bindings.
  736 +
  737 +Agora você não precisa mais usar o método `init`. Você não precisa nem tipar seus controllers se não quiser. Você pode começar seus controllers e services num lugar apropriado para isso.
  738 +
  739 +A classe Binding é uma classe que vai desacoplar a injeção de dependência, enquanto liga as rotas ao gerenciador de estados e o gerenciador de dependências.
  740 +
  741 +Isso permite Get saber qual tela está sendo mostrada quando um controller particular é usado e saber onde e como descartar o mesmo.
  742 +
  743 +Somando a isso, a classe Binding vai permitir que você tenha um controle de configuração SmartManager. Você pode configurar as dependências que serão organizadas quando for remover a rota da stack, ou quando o widget que usa ele é definido, ou nada disso. Você vai ter gerenciador de dependências inteligente trabalhando para você, e você pode configurá-lo como quiser.
  744 +
  745 +### Como utilizar:
  746 +* Para usar essa API você só precisa criar uma classe que implementa a Bindings:
  747 +
  748 +```dart
  749 +class HomeBinding implements Bindings {}
  750 +```
  751 +
  752 +Sua IDE vai automaticamente te perguntar para dar override no método `dependencies()`, aí você clica na lâmpada, clica em "override the method", e insira todas as classes que você vai usar nessa rota:
  753 +
  754 +```dart
  755 +class HomeBinding implements Bindings{
  756 + @override
  757 + void dependencies() {
  758 + Get.lazyPut<ControllerX>(() => ControllerX());
  759 + Get.lazyPut<Service>(()=> Api());
  760 + }
  761 +}
  762 +```
  763 +
  764 +Agora você só precisa informar sua rota que você vai usar esse binding para fazer a conexão entre os gerenciadores de rotas, dependências e estados.
  765 +
  766 +Usando rotas nomeadas
  767 +```dart
  768 +namedRoutes: {
  769 + '/': GetRoute(Home(), binding: HomeBinding())
  770 +}
  771 +```
282 772
  773 +Usando rotas normais:
283 ```dart 774 ```dart
284 -Controller controller = Get.delete(Controller()); 775 +Get.to(Home(), binding: HomeBinding());
285 ``` 776 ```
286 -Pronto, você consegue fazer mais com menos código, diminuiu o tamanho de código do seu app, e agora tem um gerenciador de instâncias ultra leve, com apenas 1 biblioteca.  
287 777
288 -## Navegando com rotas nomeadas:  
289 -- Se você prefere navegar por rotas nomeadas, o Get também dá suporte a isso. 778 +Então, você não vai precisar se preocupar com gerenciamento da memória da sua aplicação mais, Get vai fazer para você.
  779 +
  780 +
  781 +## Workers
  782 +Workers vai te dar suporte, ativando callbacks específicos quando um evento ocorrer.
  783 +
  784 +```dart
  785 +/// Chamada toda vez que a variável for alterada
  786 +ever(count1, (value) => print("novo valor: $value"));
  787 +
  788 +/// Chamada apenas na primeira vez que a variável for alterada
  789 +once(count1, (value) => print("novo valor: $value (não vai mudar mais)"));
  790 +
  791 +/// Anti DDos - Chamada toda vez que o usuário parar de digitar por 1 segundo, por exemplo.
  792 +debounce(count1, (value) => print("debouce $value"), time: Duration(seconds: 1));
  793 +
  794 +/// Ignore todas as mudanças num período de 1 segundo.
  795 +interval(count1, (value) => print("interval $value"), time: Duration(seconds: 1));
  796 +```
  797 +- **ever**
  798 +é chamado toda vez que a variável mudar de valor. É só isso.
  799 +
  800 +- **once**
  801 +é chamado somente na primeira vez que a variável mudar de valor.
  802 +
  803 +- **debounce**
  804 +É muito útil em funções de pesquisa, onde você somente quer que a API seja chamada depois que o usuário terminar de digitar. Normalmente, se o usuário digitar "Jonny", será feita 5 requests na sua API, pelas letras 'J', 'o', 'n', 'n' e 'y'. Com o `debounce` isso não acontece, porque você tem a sua disposição uma função que só fazer a pesquisa na api quando o usuário parar de digitar. O `debounce` é bom para táticas anti-DDos, para funções de pesquisa em que cada letra digitada ativaria um request na API. Debounce vai esperar o usário parar de digitar o nome, para então fazer o request para API.
  805 +
  806 +- **interval**
  807 +Quando se usa `debounce` , se o usuário fizer 1000 mudanças numa variável em 1 segundo, o `debounce` só computa a última mudança feita após a inatividade por um tempo estipulado (o padrão é 800 milisegundos). `interval` por outro lado vai ignorar todas as ações do usuário pelo período estipulado. Se o `interval` for de 1 segundo, então ele só conseguirá enviar 60 eventos por segundo. Se for 3 segundos de prazo, então o `interval` vai enviar 20 eventos por minuto (diferente do `debounce` que só enviaria o evento depois que o prazo estipulado acabar). Isso é recomendado para evitar abuso em funções que o usuário pode clicar rapidamente em algo para ter uma vantagem. Para exemplificar, imagine que o usuário pode ganhar moedas clicando num botão. Se ele clicar 300 vezes no botão em um minuto, ele vai ganhar 300 moedas. Usando o `interval`, você pode definir um prazo de 1 segundo por exemplo, e mesmo se ele clicasse 300 vezes em um minuto, ele ganharia apenas 60 moedas. Se fosse usado o `debounce`, o usuário ganharia apenas 1 moeda, porque só é executado quando o usuário para de clicar por um prazo estabelecido.
  808 +
  809 +## Navegar com rotas nomeadas
  810 +- Se você prefere navegar por rotas nomeadas, Get também dá suporte a isso:
290 811
291 Para navegar para uma nova tela 812 Para navegar para uma nova tela
292 ```dart 813 ```dart
293 -Get.toNamed("/NextScreen"); 814 +Get.toNamed("/ProximaTela");
294 ``` 815 ```
  816 +
295 Para navegar para uma tela sem a opção de voltar para a rota atual. 817 Para navegar para uma tela sem a opção de voltar para a rota atual.
296 ```dart 818 ```dart
297 -Get.offNamed("/NextScreen"); 819 +Get.offNamed("/ProximaTela");
298 ``` 820 ```
  821 +
299 Para navegar para uma nova tela e remover todas rotas anteriores da stack 822 Para navegar para uma nova tela e remover todas rotas anteriores da stack
300 ```dart 823 ```dart
301 -Get.offAllNamed("/NextScreen"); 824 +Get.offAllNamed("/ProximaTela");
  825 +```
  826 +
  827 +Para definir rotas, use o `GetMaterialApp`:
  828 +```dart
  829 +void main() {
  830 + runApp(
  831 + GetMaterialApp(
  832 + initialRoute: '/',
  833 + namedRoutes: {
  834 + '/': GetRoute(page: MyHomePage()),
  835 + '/login': GetRoute(page: Login()),
  836 + '/cadastro': GetRoute(page: Cadastro(),transition: Transition.cupertino);
  837 + },
  838 + )
  839 + );
  840 +}
302 ``` 841 ```
303 842
304 -### Enviando dados por rotas nomeadas: 843 +### Enviar dados para rotas nomeadas
305 844
306 -Apenas envie o que você quiser por argumentos. Get aceita qualquer coisa aqui, não importa se é uma String, um Map, uma List, int ou até uma instancia de classe. 845 +Apenas envie o que você quiser no parâmetro `arguments`. Get aceita qualquer coisa aqui, seja String, Map, List, ou até a instância de uma classe.
307 ```dart 846 ```dart
308 -Get.toNamed("/NextScreen", arguments: 'Get is the best'); 847 +Get.toNamed("/ProximaTela", arguments: 'Get é o melhor');
309 ``` 848 ```
310 -Agora você pode recuperar em sua classe ou em seu controller:  
311 849
  850 +Na sua classe ou controller:
312 ```dart 851 ```dart
313 -print(Get.arguments);  
314 -//print out: Get is the best 852 +print(Get.arguments); //valor: Get é o melhor
315 ``` 853 ```
  854 +#### Links de Url dinâmicos
316 855
317 -## Configurando rotas nomeadas e adicionando suporte completo à urls amigáveis do Flutter Web 856 +Get oferece links de url dinâmicos assim como na Web.
  857 +Desenvolvedores Web provavelmente já queriam essa feature no Flutter, e muito provavelmente viram um package que promete essa feature mas entrega uma sintaxe totalmente diferente do que uma url teria na web, mas o Get também resolve isso.
  858 +```dart
  859 +Get.offAllNamed("/ProximaTela?device=phone&id=354&name=Enzo");
  860 +```
  861 +na sua classe controller/bloc/stateful/stateless:
  862 +```dart
  863 +print(Get.parameters['id']); // valor: 354
  864 +print(Get.parameters['name']); // valor: Enzo
  865 +```
318 866
319 -### Se você ainda não adicionou " navigatorKey: Get.key," ao seu MaterialApp, faça agora. aproveite para adicionar uma "initialRoute" e o seu "onGenerateRoute". 867 +Você também pode receber parâmetros nomeados com o Get facilmente:
  868 +```dart
  869 +void main() => runApp(
  870 + GetMaterialApp(
  871 + initialRoute: '/',
  872 + namedRoutes: {
  873 + '/': GetRoute(page: MyHomePage()),
  874 + /// Importante! ':user' não é uma nova rota, é somente uma
  875 + /// especificação do parâmentro. Não use '/segunda/:user/' e '/segunda'
  876 + /// se você precisa de uma nova rota para o user, então
  877 + /// use '/segunda/user/:user' se '/segunda' for uma rota
  878 + '/segunda/:user': GetRoute(page: Segunda()), // recebe a ID
  879 + '/terceira': GetRoute(page: Terceira(),transition: Transition.cupertino);
  880 + },
  881 + ),
  882 +);
  883 +```
  884 +Envie dados na rota nomeada
  885 +```dart
  886 +Get.toNamed("/segunda/34954");
  887 +```
320 888
  889 +Na segunda tela receba os dados usando `Get.parameters[]`
321 ```dart 890 ```dart
322 -void main() {  
323 - runApp(MaterialApp(  
324 - onGenerateRoute: Router.generateRoute,  
325 - initialRoute: "/",  
326 - navigatorKey: Get.key,  
327 - title: 'Navigation',  
328 - ));  
329 -} 891 +print(Get.parameters['user']); // valor: 34954
330 ``` 892 ```
331 -Crie uma classe para gerenciar suas rotas nomeadas, você pode (e deve) copiar esse exemplo  
332 -  
333 -```dart  
334 -class Router {  
335 - static Route<dynamic> generateRoute(RouteSettings settings) {  
336 - switch (settings.name) {  
337 - case '/':  
338 - return GetRoute(  
339 - page: First(),  
340 - settings: settings,  
341 - );  
342 - case '/second':  
343 - return GetRoute(  
344 - settings: settings, page: Second(), transition: Transition.fade);  
345 - case '/third':  
346 - return GetRoute(  
347 - settings: settings,  
348 - page: Third(),  
349 - popGesture: true,  
350 - transition: Transition.cupertino);  
351 - default:  
352 - return GetRoute(  
353 - settings: settings,  
354 - transition: Transition.fade,  
355 - page: Scaffold(  
356 - body:  
357 - Center(child: Text('No route defined for ${settings.name}')),  
358 - )); 893 +
  894 +E agora, tudo que você precisa fazer é usar `Get.toNamed)` para navegar por suas rotas nomeadas, sem nenhum `context` (você pode chamar suas rotas diretamente do seu BLoc ou do Controller), e quando seu aplicativo é compilado para a web, suas rotas vão aparecer na url ❤
  895 +
  896 +
  897 +#### Middleware
  898 +
  899 +Se você quer escutar eventos do Get para ativar ações, você pode usar `routingCallback` para isso
  900 +```dart
  901 +GetMaterialApp(
  902 + routingCallback: (route){
  903 + if(routing.current == '/segunda'){
  904 + openAds();
359 } 905 }
360 } 906 }
361 -} 907 +)
362 ``` 908 ```
363 909
364 -E agora, tudo que você precisa fazer é usar Get.toNamed() para navegar pelas rotas nomeadas, sem qualquer context (você pode chamar suas rotas diretamente da sua classe BLoC ou Controller) e, quando o aplicativo for compilado na Web, suas rotas aparecerão na URL <3  
365 -  
366 -#### Middleware  
367 -Se você deseja ouvir eventos de navegação para acionar ações, é possível adicionar um GetObserver ao seu materialApp. Isso é extremamente útil para acionar eventos sempre que uma tela específica é exibida na tela. Atualmente no Flutter, você teria que colocar o evento no initState e aguardar uma possível resposta em um navigator.pop (context); para conseguir isso. Mas com o Get, isso é extremamente simples!  
368 -  
369 -##### add GetObserver(); 910 +Se você não estiver usando o `GetMaterialApp`, você pode usar a API manual para anexar um observer Middleware.
370 ```dart 911 ```dart
371 void main() { 912 void main() {
372 - runApp(MaterialApp(  
373 - onGenerateRoute: Router.generateRoute,  
374 - initialRoute: "/",  
375 - navigatorKey: Get.key,  
376 - navigatorObservers: [  
377 - GetObserver(MiddleWare.observer), // HERE !!!  
378 - ],  
379 - )); 913 + runApp(
  914 + MaterialApp(
  915 + onGenerateRoute: Router.generateRoute,
  916 + initialRoute: "/",
  917 + navigatorKey: Get.key,
  918 + navigatorObservers: [
  919 + GetObserver(MiddleWare.observer), // AQUI !!!
  920 + ],
  921 + )
  922 + );
380 } 923 }
381 ``` 924 ```
382 -Create a MiddleWare class  
383 925
  926 +Criar uma classe MiddleWare
384 ```dart 927 ```dart
385 class MiddleWare { 928 class MiddleWare {
386 static observer(Routing routing) { 929 static observer(Routing routing) {
387 - /// Você pode ouvir além das rotas, snackbars, caixas de diálogo e bottomsheets em cada tela.  
388 - /// Se você precisar inserir qualquer um desses 3 eventos diretamente aqui,  
389 -   /// você deve especificar que o evento é != Do que você está tentando fazer ou você terá um loop.  
390 - if (routing.current == '/second' && !routing.isSnackbar) {  
391 - Get.snackbar("Hi", "You are on second route");  
392 - } else if (routing.current =='/third'){  
393 - print('last route called'); 930 + /// Você pode escutar junto com as rotas, snackbars, dialogs
  931 + /// e bottomsheets em cada tela.
  932 + /// Se você precisar entrar em algum um desses 3 eventos aqui diretamente,
  933 + /// você precisa especificar que o evento é != do que você está tentando fazer
  934 + if (routing.current == '/segunda' && !routing.isSnackbar) {
  935 + Get.snackbar("Olá", "Você está na segunda rota");
  936 + } else if (routing.current =='/terceira'){
  937 + print('última rota chamada');
394 } 938 }
395 } 939 }
396 } 940 }
397 ``` 941 ```
398 -Agora é só usar o Get em seu código:  
399 942
  943 +Agora, use Get no seu código:
400 ```dart 944 ```dart
401 -class First extends StatelessWidget { 945 +class Primeira extends StatelessWidget {
402 @override 946 @override
403 Widget build(BuildContext context) { 947 Widget build(BuildContext context) {
404 return Scaffold( 948 return Scaffold(
@@ -406,16 +950,16 @@ class First extends StatelessWidget { @@ -406,16 +950,16 @@ class First extends StatelessWidget {
406 leading: IconButton( 950 leading: IconButton(
407 icon: Icon(Icons.add), 951 icon: Icon(Icons.add),
408 onPressed: () { 952 onPressed: () {
409 - Get.snackbar("hi", "i am a modern snackbar"); 953 + Get.snackbar("Oi", "eu sou uma snackbar moderna");
410 }, 954 },
411 ), 955 ),
412 - title: Text('First Route'), 956 + title: Text('Primeira rota'),
413 ), 957 ),
414 body: Center( 958 body: Center(
415 child: RaisedButton( 959 child: RaisedButton(
416 - child: Text('Open route'), 960 + child: Text('Abrir rota'),
417 onPressed: () { 961 onPressed: () {
418 - Get.toNamed("/second"); 962 + Get.toNamed("/segunda");
419 }, 963 },
420 ), 964 ),
421 ), 965 ),
@@ -423,7 +967,7 @@ class First extends StatelessWidget { @@ -423,7 +967,7 @@ class First extends StatelessWidget {
423 } 967 }
424 } 968 }
425 969
426 -class Second extends StatelessWidget { 970 +class Segunda extends StatelessWidget {
427 @override 971 @override
428 Widget build(BuildContext context) { 972 Widget build(BuildContext context) {
429 return Scaffold( 973 return Scaffold(
@@ -431,16 +975,16 @@ class Second extends StatelessWidget { @@ -431,16 +975,16 @@ class Second extends StatelessWidget {
431 leading: IconButton( 975 leading: IconButton(
432 icon: Icon(Icons.add), 976 icon: Icon(Icons.add),
433 onPressed: () { 977 onPressed: () {
434 - Get.snackbar("hi", "i am a modern snackbar"); 978 + Get.snackbar("Oi", "eu sou uma snackbar moderna");
435 }, 979 },
436 ), 980 ),
437 - title: Text('second Route'), 981 + title: Text('Segunda rota'),
438 ), 982 ),
439 body: Center( 983 body: Center(
440 child: RaisedButton( 984 child: RaisedButton(
441 - child: Text('Open route'), 985 + child: Text('Abrir rota'),
442 onPressed: () { 986 onPressed: () {
443 - Get.toNamed("/third"); 987 + Get.toNamed("/terceira");
444 }, 988 },
445 ), 989 ),
446 ), 990 ),
@@ -448,19 +992,19 @@ class Second extends StatelessWidget { @@ -448,19 +992,19 @@ class Second extends StatelessWidget {
448 } 992 }
449 } 993 }
450 994
451 -class Third extends StatelessWidget { 995 +class Terceira extends StatelessWidget {
452 @override 996 @override
453 Widget build(BuildContext context) { 997 Widget build(BuildContext context) {
454 return Scaffold( 998 return Scaffold(
455 appBar: AppBar( 999 appBar: AppBar(
456 - title: Text("Third Route"), 1000 + title: Text("Terceira Rota"),
457 ), 1001 ),
458 body: Center( 1002 body: Center(
459 child: RaisedButton( 1003 child: RaisedButton(
460 onPressed: () { 1004 onPressed: () {
461 Get.back(); 1005 Get.back();
462 }, 1006 },
463 - child: Text('Go back!'), 1007 + child: Text('Voltar!'),
464 ), 1008 ),
465 ), 1009 ),
466 ); 1010 );
@@ -468,121 +1012,167 @@ class Third extends StatelessWidget { @@ -468,121 +1012,167 @@ class Third extends StatelessWidget {
468 } 1012 }
469 ``` 1013 ```
470 1014
  1015 +### Change Theme
  1016 +Por favor não use nenhum widget acima do `GetMaterialApp` para atualizá-lo. Isso pode ativar keys duplicadas. Muitas pessoas estão acostumadas com a forma pré-história de criar um widget `ThemeProvider` só pra mudar o tema do seu app, e isso definitamente NÃO é necessário com o Get.
471 1017
472 -### APIs Avançadas  
473 -A cada dia, o Get fica mais longe do Framework padrão e fornece uma gama mais ampla de recursos que são impensáveis de serem executados usando o Flutter padrão.  
474 -Com o Get 1.17.0, foi lançada uma série de novas APIs, que permitem por exemplo, o acesso dos argumentos de uma rota nomeada de qualquer lugar do código, se há alguma snackbar ou caixa de diálogo aberta naquele momento ou qual tela está sendo exibida para o usuário.  
475 -Este é um grande passo para desanexar completamente a navegação Flutter de InheritedWidgets. Usar o contexto para acessar o InheritedWidget para usar um recurso simples de navegação é uma das únicas coisas chatas que se pode encontrar nessa estrutura incrível que é o Flutter. Agora, o Get resolveu esse problema, tornou-se onisciente e você terá acesso a basicamente qualquer ferramenta do Flutter que está disponível apenas na árvore de widgets usando o Get.  
476 -  
477 -Todas as APIs disponíveis aqui estão na fase beta; elas são totalmente funcionais, passaram em testes internos, mas como foram recém lançadas, não tem maturidade suficiente para garantir sua estabilidade. Get é totalmente estável (quase sempre issues abertas são solicitações de recursos, quase nunca bugs), mas esse conjunto de APIs foi lançado recentemente, portanto, se você encontrar algum erro aqui, abra um problema ou ofereça um PR.  
478 -  
479 -- Obrigatório: para ter acesso a essa API, você deve obrigatoriamente inserir o GetObserver em seu MaterialApp  
480 - 1018 +Você pode criar seu tema customizado e simplesmente adicionar ele dentro de `Get.changeTheme()` sem nenhum boilerplate para isso:
481 ```dart 1019 ```dart
482 -MaterialApp(  
483 - navigatorKey: Get.key,  
484 - navigatorObservers: [GetObserver()], // COLOQUE AQUI !!!!  
485 - ); 1020 +Get.changeTheme(ThemeData.light());
486 ``` 1021 ```
487 1022
488 -Você também poderá usar seu próprio Middleware no GetObserver, isso não influenciará em nada.  
489 - 1023 +Se você quer criar algo como um botão que muda o tema com um toque, você pode combinar duas APIs do Get para isso, a API que checa se o tema dark está sendo usado, e a API de mudança de tema. E dentro de um `onPressed` você coloca isso:
490 ```dart 1024 ```dart
491 -MaterialApp(  
492 - navigatorKey: Get.key,  
493 - navigatorObservers: [GetObserver(MiddleWare.observer)], // AQUI  
494 - ); 1025 +Get.changeTheme(Get.isDarkMode? ThemeData.light(): ThemeData.dark());
495 ``` 1026 ```
  1027 +Quando o modo escuro está ativado, ele vai alterar para o modo claro, e vice versa.
496 1028
497 -Principais APIs: 1029 +Se você quer saber a fundo como mudar o tema, você pode seguir esse tutorial no Medium que até te ensina a persistir o tema usando Get e shared_preferences:
  1030 +- [Dynamic Themes in 3 lines using Get](https://medium.com/swlh/flutter-dynamic-themes-in-3-lines-c3b375f292e3) - Tutorial by [Rod Brown](https://github.com/RodBr).
498 1031
  1032 +### Configurações Globais Opcionais
  1033 +Você pode mudar configurações globais para o Get. Apenas adicione `Get.config` no seu código antes de ir para qualquer rota ou faça diretamente no seu GetMaterialApp
499 ```dart 1034 ```dart
500 -Get.arguments // Te dá os argumentos da rota aberta em qualquer lugar do seu código.  
501 - // você não precisa mais recebê-los, inicializa-los no seu initState e enviar por parâmetro ao seu controller/Bloc, Get é onisciente, ele sabe exatamente qual rota está aberta e quais argumentos enviados para ela. Você pode usar isso diretamente no seu controller/bloc sem medo. 1035 +// essa forma
  1036 +GetMaterialApp(
  1037 + enableLog: true,
  1038 + defaultTransition: Transition.fade,
  1039 + opaqueRoute: Get.isOpaqueRouteDefault,
  1040 + popGesture: Get.isPopGestureEnable,
  1041 + transitionDuration: Get.defaultDurationTransition,
  1042 + defaultGlobalState: Get.defaultGlobalState,
  1043 +);
  1044 +
  1045 +// ou essa
  1046 +Get.config(
  1047 + enableLog = true,
  1048 + defaultPopGesture = true,
  1049 + defaultTransition = Transitions.cupertino
  1050 +)
  1051 +
  1052 +### Nested Navigators
502 1053
503 -Get.previousArguments // Te dá os argumentos da rota anterior. 1054 +Get fez a navegação aninhada no Flutter mais fácil ainda. Você não precisa do `context`, e você encontrará sua `navigation stack` pela ID.
504 1055
505 -Get.previousRoute // Te dá o nome da rota anterior 1056 +* Nota: Criar navegação paralela em stacks pode ser perigoso. O idela é não usar `NestedNavigators`, ou usar com moderação. Se o seu projeto requer isso, vá em frente, mas fique ciente que manter múltiplas stacks de navegação na memória pode não ser uma boa ideia no quesito consumo de RAM.
506 1057
507 -Get.rawRoute // te dá acesso à rota crua, para explorar APIs de baixo nível 1058 +Veja como é simples:
  1059 +```dart
  1060 +Navigator(
  1061 + key: nestedKey(1), // crie uma key com um index
  1062 + initialRoute: '/',
  1063 + onGenerateRoute: (settings) {
  1064 + if (settings.name == '/') {
  1065 + return GetRouteBase(
  1066 + page: Scaffold(
  1067 + appBar: AppBar(
  1068 + title: Text("Principal"),
  1069 + ),
  1070 + body: Center(
  1071 + child: FlatButton(
  1072 + color: Colors.blue,
  1073 + child: Text("Ir para a segunda"),
  1074 + onPressed: () {
  1075 + Get.toNamed('/segunda', id:1); // navega pela sua navegação aninhada usando o index
  1076 + },
  1077 + )
  1078 + ),
  1079 + ),
  1080 + );
  1081 + } else if (settings.name == '/segunda') {
  1082 + return GetRouteBase(
  1083 + page: Center(
  1084 + child: Scaffold(
  1085 + appBar: AppBar(
  1086 + title: Text("Principal"),
  1087 + ),
  1088 + body: Center(
  1089 + child: Text("Segunda")
  1090 + ),
  1091 + ),
  1092 + ),
  1093 + );
  1094 + }
  1095 + }
  1096 +),
  1097 +```
508 1098
509 -Get.routing // te dá acesso à Rounting API do GetObserver 1099 +```
  1100 +### Outras APIs avançadas e Configurações Manuais
510 1101
511 -Get.isSnackbarOpen // verifique se a snackbar está sendo exibida na tela 1102 +GetMaterialApp configura tudo para você, mas se quiser configurar Get manualmente, você pode usando APIs avançadas.
  1103 +```dart
  1104 +MaterialApp(
  1105 + navigatorKey: Get.key,
  1106 + navigatorObservers: [GetObserver()],
  1107 +);
  1108 +```
512 1109
513 -Get.isDialogOpen // verifique se a caixa de diálogo está sendo exibida na tela 1110 +Você também será capaz de usar seu próprio Middleware dentro do GetObserver, isso não irá influenciar em nada.
  1111 +```dart
  1112 +MaterialApp(
  1113 + navigatorKey: Get.key,
  1114 + navigatorObservers: [GetObserver(MiddleWare.observer)], // Aqui
  1115 +);
  1116 +```
514 1117
515 -Get.isBottomSheetOpen // verifique se a bottomsheet está sendo exibida na tela 1118 +```dart
  1119 +// fornece os arguments da tela atual
  1120 +Get.arguments
516 1121
  1122 +// fornece os arguments da rota anterior
  1123 +Get.previousArguments
517 1124
518 -```  
519 -### Nested Navigators 1125 +// fornece o nome da rota anterior
  1126 +Get.previousRoute
520 1127
521 -Get fez a navegação aninhada do Flutter ainda mais fácil.  
522 -Você não precisa do contexto e encontrará sua pilha de navegação por um ID exclusivo. 1128 +// fornece a rota bruta para acessar por exemplo, rawRoute.isFirst()
  1129 +Get.rawRoute
523 1130
524 -Veja como é simples: 1131 +// fornece acesso a API de rotas de dentro do GetObserver
  1132 +Get.routing
525 1133
526 -```dart  
527 - Navigator(  
528 - key: nestedKey(1), // crie sua key por um index  
529 - initialRoute: '/',  
530 - onGenerateRoute: (settings) {  
531 - if (settings.name == '/') {  
532 - return GetRoute(  
533 - page: Scaffold(  
534 - appBar: AppBar(  
535 - title: Text("Main"),  
536 - ),  
537 - body: Center(  
538 - child: FlatButton(  
539 - color: Colors.blue,  
540 - onPressed: () {  
541 - Get.toNamed('/second', 1); // navegue por sua rota aninhada usando o index  
542 - },  
543 - child: Text("Go to second")),  
544 - ),  
545 - ),  
546 - );  
547 - } else if (settings.name == '/second') {  
548 - return GetRoute(  
549 - page: Center(  
550 - child: Scaffold(  
551 - appBar: AppBar(  
552 - title: Text("Main"),  
553 - ),  
554 - body: Center(  
555 - child: Text("second")  
556 - ),  
557 - ),  
558 - ),  
559 - );  
560 - }  
561 - }),  
562 -``` 1134 +// checa se o snackbar está aberto
  1135 +Get.isSnackbarOpen
563 1136
  1137 +// checa se o dialog está aberto
  1138 +Get.isDialogOpen
564 1139
565 -### Outras APIs:  
566 -Desde quando essa biblioteca foi criada, reuni meus esforços para adicionar novos recursos e torná-la mais estável possível. Com isso, ainda há algumas APIs disponíveis que ainda não foram documentadas. Meu tempo é escasso, então vou resumir as principais aqui: 1140 +// checa se o bottomsheet está aberto
  1141 +Get.isBottomSheetOpen
567 1142
568 -```dart  
569 -Get.removeRoute() // remove uma rota 1143 +// remove uma rota.
  1144 +Get.removeRoute()
570 1145
571 -Get.until() // volta repetidamente até o predicado ser verdadeiro 1146 +// volta repetidamente até o predicate retorne true.
  1147 +Get.until()
572 1148
573 -Get.offUntil() // vá para a próxima rota e remova todas as rotas anteriores até que o predicado retornar verdadeiro. 1149 +// vá para a próxima rota e remove todas as rotas
  1150 +//anteriores até que o predicate retorne true.
  1151 +Get.offUntil()
574 1152
575 -Get.offNamedUntil() // vá para a próxima rota nomeada e remova todas as rotas anteriores até que o predicado retorne verdadeiro (namedRoutes) 1153 +// vá para a próxima rota nomeada e remove todas as
  1154 +//rotas anteriores até que o predicate retorne true.
  1155 +Get.offNamedUntil()
576 1156
577 -GetPlatform.isAndroid/isIOS/isWeb... //(Este método é totalmente compatível com o FlutterWeb, diferente do padrão "Platform.isAndroid" que usa dart:io) 1157 +// retorna qual é a plataforma
  1158 +//(Esse método é completamente compatível com o FlutterWeb,
  1159 +//diferente do método do framework "Platform.isAndroid")
  1160 +GetPlatform.isAndroid/isIOS/isWeb...
578 1161
579 -Get.height / Get.width // Equivalente ao método: MediaQuery.of(context).size.height //width 1162 +// Equivalente ao método: MediaQuery.of(context).size.height
  1163 +Get.height
580 1164
581 -Get.context // Fornece o contexto da tela em primeiro plano em qualquer lugar do seu código. 1165 +// Equivalente ao método: MediaQuery.of(context).size.width
  1166 +Get.width
582 1167
583 -Get.overlayContext // Fornece o contexto do dialogo/snackbar/bottomsheet em primeiro plano em qualquer lugar do seu código. 1168 +// forncece o context da tela em qualquer lugar do seu código.
  1169 +Get.context
584 1170
  1171 +// fornece o context de snackbar/dialog/bottomsheet em qualquer lugar do seu código.
  1172 +Get.contextOverlay
585 1173
586 ``` 1174 ```
587 1175
588 -Essa biblioteca será sempre atualizada e implementando novos recursos. Sinta-se livre para oferecer PRs e contribuir com ela. 1176 +Essa biblioteca sempre será atualizada e terá sempre nova features sendo implementadas. Sinta-se livre para oferecer PRs e contribuir com o package.
  1177 +
  1178 +