Jonny Borges
Committed by GitHub

Merge pull request #299 from Nipodemos/docs_organization

[Docs] Separating documentation in multiple files, and make main README with less information

Too many changes to show.

To preserve performance only 5 of 5+ files are displayed.

@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 2
3 *Idiomas: Español (este archivo), [Inglés](README.md), [Portugués de Brasil](README.pt-br.md).* 3 *Idiomas: Español (este archivo), [Inglés](README.md), [Portugués de Brasil](README.pt-br.md).*
4 4
5 -[![pub package](https://img.shields.io/pub/v/get.svg?label=get&color=blue)](https://pub.dev/packages/get) 5 +[![pub package](https://img.shields.io/pub/v/get.svg?label=get&color=blue)](https://pub.dev/packages/get)
6 ![building](https://github.com/jonataslaw/get/workflows/build/badge.svg) 6 ![building](https://github.com/jonataslaw/get/workflows/build/badge.svg)
7 [![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) 7 [![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)
8 <a href="https://github.com/Solido/awesome-flutter"> 8 <a href="https://github.com/Solido/awesome-flutter">
@@ -13,6 +13,22 @@ @@ -13,6 +13,22 @@
13 [![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-) 13 [![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-)
14 <!-- ALL-CONTRIBUTORS-BADGE:END --> 14 <!-- ALL-CONTRIBUTORS-BADGE:END -->
15 15
  16 +- [Sobre GetX](#sobre-getx)
  17 +- [Los tres pilares](#los-tres-pilares)
  18 + - [Gestión del Estado](#gestión-del-estado)
  19 + - [Explicación completa](#explicación-completa)
  20 + - [Gestión de Rutas](#gestión-de-rutas)
  21 + - [Explicación completa](#explicación-completa-1)
  22 + - [Gestión de dependencias](#gestión-de-dependencias)
  23 + - [Explicación completa](#explicación-completa-2)
  24 +- [Utils](#utils)
  25 + - [Cambiar de tema](#cambiar-de-tema)
  26 + - [Otras API avanzadas y configuraciones manuales](#otras-api-avanzadas-y-configuraciones-manuales)
  27 + - [Configuraciones globales opcionales](#configuraciones-globales-opcionales)
  28 +- [Rompiendo cambios desde 2.0](#rompiendo-cambios-desde-20)
  29 +
  30 +# Sobre GetX
  31 +
16 - GetX es una solución extra ligera y potente para Flutter. Combina gestión de estádo de alto rendimiento, inyección de dependencia inteligente y gestión de rutas, de forma rápida y práctica. 32 - GetX es una solución extra ligera y potente para Flutter. Combina gestión de estádo de alto rendimiento, inyección de dependencia inteligente y gestión de rutas, de forma rápida y práctica.
17 33
18 - GetX no es para todos, se enfoca en el consumo mínimo de recursos (rendimiento) ([Mira los puntos de referencia](https://github.com/jonataslaw/benchmarks)), usando una sintaxis fácil y agradable (productividad), que permite el desacoplamiento total de la vista y la lógica de negocio (organización). 34 - GetX no es para todos, se enfoca en el consumo mínimo de recursos (rendimiento) ([Mira los puntos de referencia](https://github.com/jonataslaw/benchmarks)), usando una sintaxis fácil y agradable (productividad), que permite el desacoplamiento total de la vista y la lógica de negocio (organización).
@@ -23,6 +39,24 @@ @@ -23,6 +39,24 @@
23 39
24 **GetX hace que su desarrollo sea productivo, pero ¿quiere hacerlo aún más productivo? [Agregue la extensión a su VSCode](https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets)** 40 **GetX hace que su desarrollo sea productivo, pero ¿quiere hacerlo aún más productivo? [Agregue la extensión a su VSCode](https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets)**
25 41
  42 +*¿Quieres contribuir al proyecto? Estaremos orgullosos de destacarte como uno de nuestros colaboradores. Aquí hay algunos puntos en los que puede contribuir y hacer que GetX (y Flutter) sea aún mejor.*
  43 +
  44 +- Ayudando a traducir el archivo Léame a otros idiomas.
  45 +
  46 +- Agregar documentación al archivo Léame (ni siquiera la mitad de las funciones de GetX han sido documentadas todavía).
  47 +
  48 +- Escriba artículos o haga videos que enseñen cómo usar GetX (se insertarán en el archivo Léame y en el futuro en nuestro Wiki).
  49 +
  50 +- Ofreciendo PRs para código/pruebas.
  51 +
  52 +- Incluyendo nuevas funciones.
  53 +
  54 +# Los tres pilares
  55 +
  56 +## Gestión del Estado
  57 +
  58 +Vea una explicación más detallada de la administración del estado [aquí](./docs/es_ES/state_management.md). Allí verá más ejemplos y también la diferencia entre el Gestión del Estado simple y el Gestión del Estado reactivo
  59 +
26 El proyecto "contador" creado por defecto en un nuevo proyecto en Flutter tiene más de 100 líneas (con comentarios). Para mostrar el poder de GetX, demostraré cómo hacer un "contador" cambiando el estado con cada clic, cambiando de página y compartiendo el estado entre pantallas, todo de manera organizada, separando la vista de la lógica de negocio, SOLO 26 LÍNEAS DE CÓDIGO INCLUIDOS COMENTARIOS. 60 El proyecto "contador" creado por defecto en un nuevo proyecto en Flutter tiene más de 100 líneas (con comentarios). Para mostrar el poder de GetX, demostraré cómo hacer un "contador" cambiando el estado con cada clic, cambiando de página y compartiendo el estado entre pantallas, todo de manera organizada, separando la vista de la lógica de negocio, SOLO 26 LÍNEAS DE CÓDIGO INCLUIDOS COMENTARIOS.
27 61
28 - Paso 1: 62 - Paso 1:
@@ -38,8 +72,8 @@ Nota: esto no modifica el MaterialApp del Flutter, GetMaterialApp no es una Mate @@ -38,8 +72,8 @@ Nota: esto no modifica el MaterialApp del Flutter, GetMaterialApp no es una Mate
38 Cree su clase con la lógica de negocio colocando todas las variables, métodos y controladores dentro de ella. Puede hacer que cualquier variable sea observable usando un simple ".obs". 72 Cree su clase con la lógica de negocio colocando todas las variables, métodos y controladores dentro de ella. Puede hacer que cualquier variable sea observable usando un simple ".obs".
39 73
40 ```dart 74 ```dart
41 -class Controller extends GETXController{  
42 - var count = 0.obs; 75 +class Controller extends GetXController {
  76 + var count = 0.obs;
43 increment() => count.value++; 77 increment() => count.value++;
44 } 78 }
45 ``` 79 ```
@@ -76,85 +110,16 @@ class Other extends StatelessWidget { @@ -76,85 +110,16 @@ class Other extends StatelessWidget {
76 } 110 }
77 111
78 ``` 112 ```
79 -Este es un proyecto simple pero ya deja en claro cuán poderoso es GetX. A medida que su proyecto crezca, esta diferencia se volverá más significativa. GetX fue diseñado para trabajar con equipos, pero también simplifica el trabajo de un desarrollador individual. Mejore sus plazos, entregue todo a tiempo, sin perder rendimiento. GetX no es para todos, pero si te identificaste con esa frase, ¡GET es para ti!  
80 -  
81 -- [Gestión de Rutas](#gestión-de-rutas)  
82 - - [¿Cómo utilizarlo?](#cómo-utilizarlo)  
83 - - [Navegación sin rutas nombradas](#navegación-sin-rutas-nombradas)  
84 - - [Navegación con rutas nombradas](#navegación-con-rutas-nombradas)  
85 - - [Enviar datos a rutas nombradas:](#enviar-datos-a-rutas-nombradas)  
86 - - [Enlaces de URL dinámicos](#enlaces-de-url-dinámicos)  
87 - - [Middleware](#middleware)  
88 - - [Navegación sin contexto](#navegación-sin-contexto)  
89 - - [SnackBars](#snackbars)  
90 - - [Diálogos](#diálogos)  
91 - - [BottomSheets](#bottomsheets)  
92 - - [Navegación anidada](#navegación-anidada)  
93 -- [Gestión del Estado](#gestión-del-estado)  
94 - - [Gestor de Estado Simple](#gestor-de-estado-simple)  
95 - - [Ventajas](#ventajas)  
96 - - [Uso](#uso)  
97 - - [Cómo maneja los Controllers](#cómo-maneja-los-controllers)  
98 - - [Ya no necesitará StatefulWidgets](#ya-no-necesitará-statefulwidgets)  
99 - - [Por qué existe](#por-qué-existe)  
100 - - [Otras formas de usarlo](#otras-formas-de-usarlo)  
101 - - [ID únicos](#id-únicos)  
102 - - [Reactivo STATE_MANAGER](#reactivo-state_manager)  
103 - - [Ventajas](#ventajas-1)  
104 - - [Uso](#uso-1)  
105 - - [Donde se pueden usar .obs](#donde-se-pueden-usar-obs)  
106 - - [Nota sobre listas](#nota-sobre-listas)  
107 - - [¿Por qué tengo que usar .value?](#por-qué-tengo-que-usar-value)  
108 - - [Obx()](#obx)  
109 - - [Workers:](#workers)  
110 - - [Mezclando los dos State Managers](#mezclando-los-dos-state-managers)  
111 - - [GetBuilder vs GetX vs Obx vs MixinBuilder](#getbuilder-vs-getx-vs-obx-vs-mixinbuilder)  
112 -- [Gestión de dependencias](#gestión-de-dependencias)  
113 - - [Simple Instance Manager](#simple-instance-manager)  
114 - - [Bindings](#bindings)  
115 - - [Cómo utilizar](#cómo-utilizar)  
116 - - [SmartManagement](#smartmanagement)  
117 -- [Utils](#utils)  
118 - - [Cambiar de tema](#cambiar-de-tema)  
119 - - [Otras API avanzadas y configuraciones manuales](#otras-api-avanzadas-y-configuraciones-manuales)  
120 - - [Configuraciones globales opcionales](#configuraciones-globales-opcionales)  
121 -- [Rompiendo cambios desde 2.0](#rompiendo-cambios-desde-20)  
122 -  
123 -  
124 -*¿Quieres contribuir al proyecto? Estaremos orgullosos de destacarte como uno de nuestros colaboradores. Aquí hay algunos puntos en los que puede contribuir y hacer que GetX (y Flutter) sea aún mejor.*  
125 113
126 -- Ayudando a traducir el archivo Léame a otros idiomas.  
127 -  
128 -- Agregar documentación al archivo Léame (ni siquiera la mitad de las funciones de GetX han sido documentadas todavía).  
129 -  
130 -- Escriba artículos o haga videos que enseñen cómo usar GetX (se insertarán en el archivo Léame y en el futuro en nuestro Wiki).  
131 -  
132 -- Ofreciendo PRs para código/pruebas.  
133 -  
134 -- Incluyendo nuevas funciones.  
135 -  
136 -# Gestión de Rutas  
137 -  
138 -Cualquier contribución es bienvenida!  
139 -  
140 -## ¿Cómo utilizarlo?  
141 -  
142 -Agregue esto a su archivo pubspec.yaml: 114 +Este es un proyecto simple pero ya deja en claro cuán poderoso es GetX. A medida que su proyecto crezca, esta diferencia se volverá más significativa. GetX fue diseñado para trabajar con equipos, pero también simplifica el trabajo de un desarrollador individual. Mejore sus plazos, entregue todo a tiempo, sin perder rendimiento. GetX no es para todos, pero si te identificaste con esa frase, ¡GET es para ti!
143 115
144 -```  
145 -dependencies:  
146 - get:  
147 -``` 116 +### Explicación completa
148 117
149 -Si va a utilizar rutas/snackbars/dialogs/bottomsheets sin contexto, o las APIs de GetX de alto nivel, simplemente debe agregar "Get" antes de su MaterialApp, ¡convertirlo en GetMaterialApp y disfrutar! 118 +**Vea una explicación más detallada de la administración del estado [aquí](./docs/es_ES/state_management.md). Allí verá más ejemplos y también la diferencia entre el Gestión del Estado simple y el Gestión del Estado reactivo**
150 119
151 -```dart  
152 -GetMaterialApp( // Before: MaterialApp(  
153 - home: MyHome(),  
154 -)  
155 -``` 120 +## Gestión de Rutas
156 121
157 -## Navegación sin rutas nombradas 122 +Vea una explicación más detallada de la administración del estado [aquí](./docs/es_ES/route_management.md).
158 123
159 Para navegar a una nueva pantalla: 124 Para navegar a una nueva pantalla:
160 125
@@ -186,1195 +151,51 @@ Para navegar a la siguiente ruta y recibir o actualizar datos tan pronto como se @@ -186,1195 +151,51 @@ Para navegar a la siguiente ruta y recibir o actualizar datos tan pronto como se
186 var data = await Get.to(Payment()); 151 var data = await Get.to(Payment());
187 ``` 152 ```
188 153
189 -en la otra pantalla, envíe los datos para la ruta anterior:  
190 -  
191 -```dart  
192 -Get.back(result: 'success');  
193 -```  
194 -  
195 -Y luego usarlo:  
196 -  
197 -ej:  
198 -```dart  
199 -if(data == 'success') madeAnything();  
200 -```  
201 -  
202 -¿No quieres aprender nuestra sintaxis?  
203 -  
204 -Simplemente cambie Navigator (mayúsculas) a navigator (minúsculas), y tendrá todas las funciones de la navegación estándar, pero sin tener que usar el contexto.  
205 -  
206 -Ejemplo:  
207 -  
208 -```dart  
209 -// Default Flutter navigator  
210 -Navigator.of(context).push(  
211 - context,  
212 - MaterialPageRoute(  
213 - builder: (BuildContext context) {  
214 - return HomePage();  
215 - },  
216 - ),  
217 -);  
218 -  
219 -// Get using Flutter syntax without needing context  
220 -navigator.push(  
221 - MaterialPageRoute(  
222 - builder: (_) {  
223 - return HomePage();  
224 - },  
225 - ),  
226 -);  
227 -  
228 -// Get syntax (It is much better, but you have the right to disagree)  
229 -Get.to(HomePage());  
230 -```  
231 -  
232 -## Navegación con rutas nombradas  
233 -  
234 -- Si prefiere navegar con rutas nombradas, con GetX también es posible.  
235 -  
236 -Para navegar a la siguiente pantalla  
237 -  
238 -```dart  
239 -Get.toNamed("/NextScreen");  
240 -```  
241 -  
242 -Para navegar y eliminar la pantalla anterior del árbol.  
243 -  
244 -```dart  
245 -Get.offNamed("/NextScreen");  
246 -```  
247 -  
248 -Para navegar y eliminar todas las pantallas anteriores del árbol.  
249 -  
250 -```dart  
251 -Get.offAllNamed("/NextScreen");  
252 -```  
253 -  
254 -Para definir rutas, use GetMaterialApp:  
255 -  
256 -```dart  
257 -void main() {  
258 - runApp(  
259 - GetMaterialApp(  
260 - initialRoute: '/',  
261 - getPages: [  
262 - GetPage(name: '/', page: () => MyHomePage()),  
263 - GetPage(name: '/second', page: () => Second()),  
264 - GetPage(  
265 - name: '/third',  
266 - page: () => Third(),  
267 - transition: Transition.zoom  
268 - ),  
269 - ],  
270 - )  
271 - );  
272 -}  
273 -```  
274 -  
275 -### Enviar datos a rutas nombradas:  
276 -  
277 -Envía lo que quieras usando el parámetro arguments. GetX acepta cualquier cosa aquí, ya sea un String, Map, List o incluso una instancia de clase.  
278 -  
279 -```dart  
280 -Get.toNamed("/NextScreen", arguments: 'Get is the best');  
281 -```  
282 -  
283 -luego en su clase o controlador:  
284 -  
285 -```dart  
286 -print(Get.arguments);  
287 -//print out: Get is the best  
288 -```  
289 -  
290 -### Enlaces de URL dinámicos  
291 -  
292 -GetX ofrece URLs dinámicas avanzadas como en la Web. Los desarrolladores web probablemente ya quisieron esta característica en Flutter, y lo más probable es que hayan visto un paquete que promete esta característica y pero que ofrece una sintaxis totalmente diferente a la que una URL tendría en la web, pero GetX lo resuelve.  
293 -  
294 -```dart  
295 -Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo");  
296 -```  
297 -  
298 -y luego en su clase controller/bloc/stateful/stateless:  
299 -  
300 -```dart  
301 -print(Get.parameters['id']);  
302 -// out: 354  
303 -print(Get.parameters['name']);  
304 -// out: Enzo  
305 -```  
306 -  
307 -También puede recibir parámetros nombrados fácilmente:  
308 -  
309 -```dart  
310 -void main() {  
311 - runApp(  
312 - GetMaterialApp(  
313 - initialRoute: '/',  
314 - getPages: [  
315 - GetPage(  
316 - name: '/',  
317 - page: () => MyHomePage(),  
318 - ),  
319 - GetPage(  
320 - name: '/profile/',  
321 - page: () => MyProfile(),  
322 - ),  
323 - //You can define a different page for routes with arguments, and another without arguments, but for that you must use the slash '/' on the route that will not receive arguments as above.  
324 - GetPage(  
325 - name: '/profile/:user',  
326 - page: () => UserProfile(),  
327 - ),  
328 - GetPage(  
329 - name: '/third',  
330 - page: () => Third(),  
331 - transition: Transition.cupertino  
332 - ),  
333 - ],  
334 - )  
335 - );  
336 -}  
337 -```  
338 -  
339 -Enviar datos sobre el nombre de la ruta  
340 -  
341 -```dart  
342 -Get.toNamed("/second/34954");  
343 -```  
344 -  
345 -Y en la segunda pantalla tome los datos por parámetro  
346 -  
347 -```dart  
348 -print(Get.parameters['user']);  
349 -// out: 34954  
350 -```  
351 -  
352 -Y ahora, todo lo que necesita hacer es usar Get.toNamed() para navegar por sus rutas nombradas, sin ningún contexto (puede llamar a sus rutas directamente desde su clase BLoC o Controller), y cuando su aplicación se compila para web, sus rutas aparecerán en la url del navegador <3  
353 -  
354 -### Middleware  
355 -  
356 -Si desea escuchar eventos de GetX para activar acciones, puede usar el routingCallback:  
357 -  
358 -```dart  
359 -GetMaterialApp(  
360 - routingCallback: (routing) {  
361 - if(routing.current == '/second'){  
362 - openAds();  
363 - }  
364 - }  
365 -)  
366 -```  
367 -  
368 -Si no está usando GetMaterialApp, puede usar la API para adjuntar el observador de Middleware. 154 +### Explicación completa
369 155
370 -```dart  
371 -void main() {  
372 - runApp(  
373 - MaterialApp(  
374 - onGenerateRoute: Router.generateRoute,  
375 - initialRoute: "/",  
376 - navigatorKey: Get.key,  
377 - navigatorObservers: [  
378 - GetObserver(MiddleWare.observer), // HERE !!!  
379 - ],  
380 - ),  
381 - );  
382 -}  
383 -```  
384 -  
385 -Crear la clase MiddleWare:  
386 -  
387 -```dart  
388 -class MiddleWare {  
389 - static observer(Routing routing) {  
390 - /// You can listen in addition to the routes, the snackbars, dialogs and bottomsheets on each screen.  
391 - ///If you need to enter any of these 3 events directly here,  
392 - ///you must specify that the event is != Than you are trying to do.  
393 - if (routing.current == '/second' && !routing.isSnackbar) {  
394 - Get.snackbar("Hi", "You are on second route");  
395 - } else if (routing.current =='/third'){  
396 - print('last route called');  
397 - }  
398 - }  
399 -}  
400 -```  
401 -  
402 -Ahora, usa GetX en tu código:  
403 -  
404 -```dart  
405 -class First extends StatelessWidget {  
406 - @override  
407 - Widget build(BuildContext context) {  
408 - return Scaffold(  
409 - appBar: AppBar(  
410 - leading: IconButton(  
411 - icon: Icon(Icons.add),  
412 - onPressed: () {  
413 - Get.snackbar("hi", "i am a modern snackbar");  
414 - },  
415 - ),  
416 - title: Text('First Route'),  
417 - ),  
418 - body: Center(  
419 - child: RaisedButton(  
420 - child: Text('Open route'),  
421 - onPressed: () {  
422 - Get.toNamed("/second");  
423 - },  
424 - ),  
425 - ),  
426 - );  
427 - }  
428 -}  
429 -  
430 -class Second extends StatelessWidget {  
431 - @override  
432 - Widget build(BuildContext context) {  
433 - return Scaffold(  
434 - appBar: AppBar(  
435 - leading: IconButton(  
436 - icon: Icon(Icons.add),  
437 - onPressed: () {  
438 - Get.snackbar("hi", "i am a modern snackbar");  
439 - },  
440 - ),  
441 - title: Text('second Route'),  
442 - ),  
443 - body: Center(  
444 - child: RaisedButton(  
445 - child: Text('Open route'),  
446 - onPressed: () {  
447 - Get.toNamed("/third");  
448 - },  
449 - ),  
450 - ),  
451 - );  
452 - }  
453 -}  
454 -  
455 -class Third extends StatelessWidget {  
456 - @override  
457 - Widget build(BuildContext context) {  
458 - return Scaffold(  
459 - appBar: AppBar(  
460 - title: Text("Third Route"),  
461 - ),  
462 - body: Center(  
463 - child: RaisedButton(  
464 - onPressed: () {  
465 - Get.back();  
466 - },  
467 - child: Text('Go back!'),  
468 - ),  
469 - ),  
470 - );  
471 - }  
472 -}  
473 -```  
474 -  
475 -## Navegación sin contexto  
476 -  
477 -### SnackBars  
478 -  
479 -Para tener simple SnackBar con Flutter, debe obtener el contexto de Scaffold, o debe utilizar una GlobalKey:  
480 -  
481 -```dart  
482 -final snackBar = SnackBar(  
483 - content: Text('Hi!'),  
484 - action: SnackBarAction(  
485 - label: 'I am a old and ugly snackbar :(',  
486 - onPressed: (){}  
487 - ),  
488 -);  
489 -// Find the Scaffold in the widget tree and use  
490 -// it to show a SnackBar.  
491 -Scaffold.of(context).showSnackBar(snackBar);  
492 -```  
493 -  
494 -Con GetX esto se resume en:  
495 -  
496 -```dart  
497 -Get.snackbar('Hi', 'i am a modern snackbar');  
498 -```  
499 -  
500 -Todo lo que tiene que hacer es llamar a Get.snackbar desde cualquier parte de su código y personalizarlo como desee:  
501 -  
502 -```dart  
503 -Get.snackbar(  
504 - "Hey i'm a Get SnackBar!", // title  
505 - "It's unbelievable! I'm using SnackBar without context, without boilerplate, without Scaffold, it is something truly amazing!", // message  
506 - icon: Icon(Icons.alarm),  
507 - shouldIconPulse: true,  
508 - onTap:(){},  
509 - barBlur: 20,  
510 - isDismissible: true,  
511 - duration: Duration(seconds: 3),  
512 -);  
513 -  
514 -  
515 - ////////// ALL FEATURES //////////  
516 - // Color colorText,  
517 - // Duration duration,  
518 - // SnackPosition snackPosition,  
519 - // Widget titleText,  
520 - // Widget messageText,  
521 - // bool instantInit,  
522 - // Widget icon,  
523 - // bool shouldIconPulse,  
524 - // double maxWidth,  
525 - // EdgeInsets margin,  
526 - // EdgeInsets padding,  
527 - // double borderRadius,  
528 - // Color borderColor,  
529 - // double borderWidth,  
530 - // Color backgroundColor,  
531 - // Color leftBarIndicatorColor,  
532 - // List<BoxShadow> boxShadows,  
533 - // Gradient backgroundGradient,  
534 - // FlatButton mainButton,  
535 - // OnTap onTap,  
536 - // bool isDismissible,  
537 - // bool showProgressIndicator,  
538 - // AnimationController progressIndicatorController,  
539 - // Color progressIndicatorBackgroundColor,  
540 - // Animation<Color> progressIndicatorValueColor,  
541 - // SnackStyle snackStyle,  
542 - // Curve forwardAnimationCurve,  
543 - // Curve reverseAnimationCurve,  
544 - // Duration animationDuration,  
545 - // double barBlur,  
546 - // double overlayBlur,  
547 - // Color overlayColor,  
548 - // Form userInputForm  
549 - ///////////////////////////////////  
550 -```  
551 -  
552 -Si prefiere el snackbar tradicional, o desea personalizarlo desde cero, inclyendo reducirlo a una sola línea de código (dado que Get.snackbar utiliza al menos un título y un mensaje obligatorios), puede usar `Get.rawSnackbar();` que proporciona la API en la que se creó el Get.snackbar.  
553 -  
554 -### Diálogos  
555 -  
556 -Para abrir el dialog:  
557 -  
558 -```dart  
559 -Get.dialog(YourDialogWidget());  
560 -```  
561 -  
562 -Para abrir un dialog predeterminado:  
563 -  
564 -```dart  
565 -Get.defaultDialog(  
566 - onConfirm: () => print("Ok"),  
567 - middleText: "Dialog made in 3 lines of code"  
568 -);  
569 -```  
570 -  
571 -También puede usar Get.generalDialog en lugar de showGeneralDialog.  
572 -  
573 -Para todos los demás dialogs de Flutter, incluidos los cupertinos, puede usar Get.overlayContext en lugar de context, y abrirlo en cualquier parte de su código.  
574 -  
575 -Para los widgets que no usan Overlay, puede usar Get.context.  
576 -  
577 -Estos dos contexts funcionarán en el 99% de los casos para reemplazar el context de su UI, excepto en los casos donde inheritedWidget es usado sin un contexto de navegación.  
578 -  
579 -### BottomSheets  
580 -  
581 -Get.bottomSheet es como showModalBottomSheet, pero no necesita contexto.  
582 -  
583 -```dart  
584 -Get.bottomSheet(  
585 - Container(  
586 - child: Wrap(  
587 - children: <Widget>[  
588 - ListTile(  
589 - leading: Icon(Icons.music_note),  
590 - title: Text('Music'),  
591 - onTap: () => {}  
592 - ),  
593 - ListTile(  
594 - leading: Icon(Icons.videocam),  
595 - title: Text('Video'),  
596 - onTap: () => {},  
597 - ),  
598 - ],  
599 - ),  
600 - );  
601 -);  
602 -```  
603 -  
604 -## Navegación anidada 156 +**Vea una explicación más detallada de la Gestión de Rutas [aquí](./docs/es_ES/route_management.md).**
605 157
606 -GetX hizo la navegación anidada de Flutter aún más fácil. 158 +## Gestión de dependencias
607 159
608 -No necesita el contexto, y encontrará su pila de navegación por Id. 160 +Vea una explicación más detallada de la Gestión de dependencias [aquí](./docs/es_ES/dependency_management.md).
609 161
610 -- NOTA: Crear pilas de navegación paralelas puede ser peligroso. Lo ideal es no usar NestedNavigators o hacerlo con moderación. Si su proyecto lo requiere, continúe, pero tenga en cuenta que mantener múltiples pilas de navegación en la memoria puede no ser una buena idea para el consumo de RAM.  
611 -  
612 -Mira qué simple es:  
613 -  
614 -```dart  
615 -Navigator(  
616 - key: Get.nestedKey(1), // create a key by index  
617 - initialRoute: '/',  
618 - onGenerateRoute: (settings) {  
619 - if (settings.name == '/') {  
620 - return GetPageRoute(  
621 - page: Scaffold(  
622 - appBar: AppBar(  
623 - title: Text("Main"),  
624 - ),  
625 - body: Center(  
626 - child: FlatButton(  
627 - color: Colors.blue,  
628 - onPressed: () {  
629 - Get.toNamed('/second', id:1); // navigate by your nested route by index  
630 - },  
631 - child: Text("Go to second"),  
632 - ),  
633 - ),  
634 - ),  
635 - );  
636 - } else if (settings.name == '/second') {  
637 - return GetPageRoute(  
638 - page: Center(  
639 - child: Scaffold(  
640 - appBar: AppBar(  
641 - title: Text("Main"),  
642 - ),  
643 - body: Center(  
644 - child: Text("second")  
645 - ),  
646 - ),  
647 - ),  
648 - );  
649 - }  
650 - }  
651 -),  
652 -```  
653 -  
654 -# Gestión del Estado  
655 -  
656 -Actualmente hay varios State Managers para Flutter. Sin embargo, con la mayoría de ellos implica utilizar ChangeNotifier para actualizar widgets y este es un enfoque malo y muy malo para el rendimiento de aplicaciones medianas o grandes. Puede verificar en la documentación oficial de Flutter que [ChangeNotifier debe usarse con 1 o un máximo de 2 listeners](https://api.Flutter.dev/Flutter/foundation/ChangeNotifier-class.html), por lo que es prácticamente inutilizable para cualquier aplicación mediana o grande.  
657 -  
658 -Otros state managers son buenos, pero tienen sus matices:  
659 -  
660 -- BLoC es muy seguro y eficiente, pero es muy complejo para principiantes, lo que ha impedido que las personas se desarrollen con Flutter.  
661 -  
662 -- MobX es más fácil que BLoC y reactivo, casi perfecto, diría, pero necesita usar un generador de código, que para aplicaciones grandes, reduce la productividad, ya que necesitará beber muchos cafés hasta que su código esté listo nuevamente después de un `flutter clean` (¡Y esto no es culpa de MobX, sino del codegen que es realmente lento!).  
663 -  
664 -- Provider usa InheritedWidget para entregar el mismo listener, como una forma de resolver el problema mencionado anteriormente con ChangeNotifier, lo que implica que cualquier acceso a su clase ChangeNotifier debe estar dentro del árbol de widgets debido al contexto necesario para acceder.  
665 -  
666 -GetX no es mejor ni peor que cualquier otro gestor de estado, pero debe analizar estos puntos, así como los puntos que se mencionan a continuación, para elegir entre usar GetX en forma pura (vanilla) o usarlo junto con otro gestor de estado.  
667 -  
668 -Definitivamente, GetX no es enemigo de ningún otro gestor de estado, porque GetX es más bien un microframework, no solo un gestor de estado, y se puede usar solo o en combinación con ellos.  
669 -  
670 -## Gestor de Estado Simple  
671 -  
672 -GetX tiene un gestor de estado que es extremadamente ligero y fácil de implementar, especialmente para aquellos nuevos en Flutter, que no utiliza ChangeNotifier, y satisface la necesidad, y no causará problemas en aplicaciones grandes.  
673 -  
674 -### Ventajas  
675 -  
676 -1. Actualiza solo los widgets necesarios.  
677 -  
678 -2. No usa changeNotifier, es el gestor de estados que usa menos memoria (cerca de 0mb).  
679 -  
680 -3. ¡Olvídate de StatefulWidget! Con GetX nunca lo necesitarás. Con los otros state managers, probablemente tendrá que usar un StatefulWidget para obtener la instancia de su Provider,BLoC,MobX Controller, etc. Pero alguna vez se detuvo para pensar que su appBar, su Scaffold y la mayoría de los widgets que están en tu clase son Stateless? Entonces, ¿por qué guardar el estado de una clase completa, si puede guardar solo el estado del widget que es Stateful? GetX también resuelve eso. Crea una clase Stateless, haz todo Stateless. Si necesita actualizar un solo componente, envuélvalo con GetBuilder, y se mantendrá su estado.  
681 -  
682 -4. ¡Organiza tu proyecto de verdad! Los Controllers no deben estar en su UI, colocar su TextEditController o cualquier controller que utilice dentro de su clase Controller.  
683 -  
684 -5. ¿Necesita activar un evento para actualizar un widget tan pronto como este se dibuje? GetBuilder tiene la propiedad "initState", al igual que en un StatefulWidget, y puede llamar a eventos desde su Controller, directamente desde él, sin que se coloquen más eventos en su initState.  
685 -  
686 -6. ¿Necesita activar una acción como cerrar streams, timers, etc.? GetBuilder también tiene la propiedad dispose, donde puede llamar a eventos tan pronto como se destruya ese widget.  
687 -  
688 -7. Use streams solo si es necesario. Puede usar sus StreamControllers dentro de su Controller normalmente, y usar StreamBuilder también normalmente, pero recuerde, un stream consume una cantidad azonablemente de memoria, la programación reactiva es hermosa, pero no debe abusar de ella. 30 streams abiertos simultáneamente pueden ser peores que un changeNotifier (y changeNotifier es muy malo).  
689 -  
690 -8. Actualice los widgets sin consumir ram por eso. GetX almacena solo el creator ID de GetBuilder y lo actualiza cuando es necesario. El consumo de memoria del almacenamiento del Get ID en la memoria es muy bajo, incluso para miles de GetBuilders. Cuando crea un nuevo GetBuilder, en realidad está compartiendo el estado de GetBuilder que tiene un creator ID. No se crea un nuevo estado para cada GetBuilder, lo que ahorra MUCHA RAM para aplicaciones grandes. Básicamente, su aplicación será completamente Stateless, y los pocos Widgets que serán Stateful (dentro de GetBuilder) tendrán un solo estado y por lo tanto actualizar uno los actualizará a todos. El estado es solo uno.  
691 -  
692 -9. GetX es omnisciente y, en la mayoría de los casos, sabe exactamente el momento de sacar un Controller de la memoria. No debe preocuparse por eso, GetX conoce el mejor momento para hacerlo.  
693 -  
694 -### Uso  
695 -  
696 -```dart  
697 -// Create controller class and extends GETXController  
698 -class Controller extends GETXController {  
699 - int counter = 0;  
700 - void increment() {  
701 - counter++;  
702 - update(); // use update() to update counter variable on UI when increment be called  
703 - }  
704 -}  
705 -// On your Stateless/Stateful class, use GetBuilder to update Text when increment be called  
706 -GetBuilder<Controller>(  
707 - init: Controller(), // INIT IT ONLY THE FIRST TIME  
708 - builder: (_) => Text(  
709 - '${_.counter}',  
710 - ),  
711 -)  
712 -//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.  
713 -```  
714 -  
715 -**¡Listo!**  
716 -  
717 -- Ya has aprendido a gestionar estados con GetX.  
718 -  
719 -- Nota: es posible que desee una organización más grande y no usar la propiedad init. Para eso, puede crear una clase y extender la clase Bindings, dentro de ella mencionar los Controllers que necesita crear dentro de esa ruta. Pero los Controllers no se crearán en ese momento, por el contrario, esto será solo una declaración, por lo que, la primera vez que use un Controller, GetX sabrá dónde buscarlo. GetX seguirá siendo lazyLoad y se ocupará de eliminar los controllers cuando ya no sean necesarios. Vea el ejemplo pub.dev para ver cómo funciona. 162 +- Nota: si está utilizando el gestor de estado de GetX, no tiene que preocuparse por esto, solo lea para obtener información, pero preste más atención a la API de bindings, que hará todo esto automáticamente por usted.
720 163
721 -Si navega por muchas rutas y necesita datos que estaban en su Controller utilizado previamente, solo necesita usar nuevamente GetBuilder (sin init): 164 +¿Ya estás utilizando GetX y quieres que tu proyecto sea lo más ágil posible? GetX tiene un gestor de dependencias simple y poderoso que le permite recuperar la misma clase que su BLoC o Controller con solo una líneas de código, sin contexto de Provider, sin inheritedWidget:
722 165
723 ```dart 166 ```dart
724 -class OtherClass extends StatelessWidget {  
725 - @override  
726 - Widget build(BuildContext context) {  
727 - return Scaffold(  
728 - body: Center(  
729 - child: GetBuilder<Controller>(  
730 - builder: (s) => Text('${s.counter}'),  
731 - ),  
732 - ),  
733 - );  
734 - } 167 +Controller controller = Get.put(Controller()); // Rather Controller controller = Controller();
735 ``` 168 ```
736 169
737 -Si necesita usar su Controller en muchos otros lugares y fuera de GetBuilder, simplemente cree un get en su Controller y obténgalo fácilmente. (o use `Get.find <Controller>()`) 170 +En lugar de crear una instancia de su clase dentro de la clase que está utilizando, la está creando dentro de la instancia GetX, que la hará disponible en toda su aplicación. Entonces puede usar su Controller (o BLoC) normalmente.
738 171
739 ```dart 172 ```dart
740 -class Controller extends GETXController {  
741 -  
742 - /// You do not need that. I recommend using it just for ease of syntax.  
743 - /// with static method: Controller.to.counter();  
744 - /// with no static method: Get.find<Controller>().counter();  
745 - /// There is no difference in performance, nor any side effect of using either syntax. Only one does not need the type, and the other the IDE will autocomplete it.  
746 - static Controller get to => Get.find(); // add this line  
747 -  
748 - int counter = 0;  
749 - void increment() {  
750 - counter++;  
751 - update();  
752 - }  
753 -} 173 +controller.fetchApi();
754 ``` 174 ```
755 175
756 -Y luego puede acceder a su Controller directamente, de esa manera: 176 +Imagine que ha navegado a través de numerosas rutas y necesita datos que quedaron en su controlador, necesitaría un gestor de estado combinado con Providere o Get_it, ¿correcto? No con GetX. Solo necesita pedirle a GetX que "encuentre" su controlador, no necesita dependencias adicionales:
757 177
758 ```dart 178 ```dart
759 -FloatingActionButton(  
760 - onPressed: () {  
761 - Controller.to.increment(),  
762 - } // This is incredibly simple!  
763 - child: Text("${Controller.to.counter}"),  
764 -), 179 +Controller controller = Get.find();
  180 +//Yes, it looks like Magic, Get will find your controller, and will deliver it to you. You can have 1 million controllers instantiated, Get will always give you the right controller.
765 ``` 181 ```
766 182
767 -Cuando presiona FloatingActionButton, todos los widgets que escuchan la variable 'counter' se actualizarán automáticamente.  
768 -  
769 -### Cómo maneja los Controllers  
770 -  
771 -Digamos que tenemos esto:  
772 -  
773 -`Class a => Class B (has controller X) => Class C (has controller X)`  
774 -  
775 -En la clase A, el Controller aún no está en la memoria, porque aún no lo ha utilizado (GetX es lazyLoad). En la clase B usaste el Controller y entró en la memoria. En la clase C usó el mismo Controller que en la clase B, GetX compartirá el estado del Controller B con el Controller C, y el mismo Controller todavía está en la memoria. Si cierra la pantalla C y la pantalla B, GetX eliminará automáticamente Controller X de la memoria y liberará recursos, porque la clase A no está utilizando Controller. Si navega nuevamente hacia B, Controller X ingresará nuevamente a la memoria, si en lugar de ir a la clase C, regresa nuevamente a la clase A, GetX eliminará el Controller de la misma manera. Si la clase C no usó el Controller, y usted sacó la clase B de la memoria, ninguna clase estaría usando Controller X y de la misma manera se eliminaría. La única excepción que puede interferir con GetX es si elimina B de la ruta de forma inesperada e intenta utilizar el Controller en C. En este caso, se eliminó el creator ID del Controller que estaba en B y GetX se programó para eliminar de la memoria cada controller que no tiene creator ID. Si tiene la intención de hacer esto, agregue el indicador "autoRemove: false" al GetBuilder de clase B y use "adoptID = true;" en GetBuilder de la clase C.  
776 -  
777 -### Ya no necesitará StatefulWidgets  
778 -  
779 -Usar StatefulWidgets significa almacenar el estado de pantallas enteras innecesariamente, incluso si necesita reconstruir mínimamente un widget, lo incrustará en un Consumer/Observer/BlocProvider/GetBuilder/GetX/Obx, que será será también otro StatefulWidget.  
780 -  
781 -La clase StatefulWidget es una clase más grande que StatelessWidget, que asignará más RAM, y esto puede no hacer una diferencia significativa entre una o dos clases, ¡pero sin duda lo hará cuando tenga 100 de ellas!  
782 -A menos que necesite usar un mixin, como TickerProviderStateMixin, será totalmente innecesario usar un StatefulWidget con GetX.  
783 -  
784 -Puede llamar a todos los métodos de un StatefulWidget directamente desde un GetBuilder. Si necesita llamar al método initState() o dispose(), por ejemplo, puede llamarlos directamente; 183 +Y luego podrá recuperar los datos de su controlador que se obtuvieron allí:
785 184
786 ```dart 185 ```dart
787 -GetBuilder<Controller>(  
788 - initState: (_) => Controller.to.fetchApi(),  
789 - dispose: (_) => Controller.to.closeStreams(),  
790 - builder: (s) => Text('${s.username}'),  
791 -), 186 +Text(controller.textFromApi);
792 ``` 187 ```
793 188
794 -Un enfoque mucho mejor que esto es utilizar el método onInit() y onClose() directamente desde su Controller. 189 +¿Buscando lazy loading? Puede declarar todos sus controladores, y se llamará solo cuando alguien lo necesite. Puedes hacer esto con:
795 190
796 ```dart 191 ```dart
797 -@override  
798 -void onInit() {  
799 - fetchApi();  
800 - super.onInit();  
801 -} 192 +Get.lazyPut<Service>(()=> ApiMock());
  193 +/// ApiMock will only be called when someone uses Get.find<Service> for the first time
802 ``` 194 ```
803 195
804 -- NOTA: Si desea iniciar un método en el momento en que se llama al Controller por primera vez, NO NECESITA usar constructores para esto, de hecho, usando un paquete orientado al rendimiento como GetX, esto sería casi una mala práctica, debido a que se desvía de la lógica en la que los controllers son creados o asignados (si crea una instancia de este controller, se llamará al constructor inmediatamente, completará un Controller antes de que se use, estará asignando memoria sin ser usado, esto definitivamente perjudica los principios de esta biblioteca). Los métodos onInit(); y onClose(); fueron creados para esto, se los llamará cuando se cree el controller, o se use por primera vez, dependiendo de si está utilizando GetX.lazyPut o no. Si desea, por ejemplo, hacer una llamada a su API para llenar datos, puede olvidarse del viejo método initState/dispose, simplemente inicie su llamada a la API en onInit y si necesita ejecutar algún comando como cerrar streams, use onClose() para eso.  
805 -  
806 -### Por qué existe  
807 -  
808 -El propósito de este paquete es precisamente brindarle una solución completa para la navegación de rutas, la gestión de dependencias y de estados, utilizando la menor cantidad de dependencias posibles, con un alto grado de desacoplamiento. GetX se acopla internamente a todas las API de Flutter de alto y bajo nivel, para garantizar que trabaje con el menor acoplamiento posible. Centralizamos todo en un solo paquete, para garantizar que no tenga ningún otro tipo de acoplamiento en su proyecto. De esa manera, puede poner solo widgets en su vista y dejar libre la parte de su equipo que trabaja con la lógica de negocios, sin depender de ningún elemento de la vista. Esto proporciona un entorno de trabajo mucho más limpio y ordenado, de modo tal que parte de su equipo trabajará solo con widgets, sin preocuparse por tener que enviar datos a su Controller, mientras la otra parte de su equipo trabajará solo con lógica de negocios, sin depender de ningún elemento de la UI.  
809 -  
810 -Entonces, para simplificar esto:  
811 -  
812 -No necesita llamar a métodos en initState y enviarlos por parámetro a su Controller, ni usar un constructor Controller. Para eso tiene el método onInit() que se llamará en el momento adecuado para que sus servicios sean iniciados. No necesita llamar a dispose(), dado que dispone del método onClose() que se llamará en el momento exacto en que su Controller ya no se necesita, y se eliminará de la memoria. De esa manera, deje las vistas solo para widgets, y abstenerse de incluír cualquier tipo de lógica de negocios.  
813 -  
814 -No llame a un método dispose() dentro de GETXController, no hará nada, recuerde que Controller no es un widget, no debe "eliminarlo" y GetX lo eliminará de forma automática e inteligente de la memoria. Si utilizó algún stream en él y desea cerrarlo, simplemente insértelo en el método de cierre.  
815 -  
816 -Ejemplo:  
817 -  
818 -```dart  
819 -class Controller extends GETXController {  
820 - StreamController<User> user = StreamController<User>();  
821 - StreamController<String> name = StreamController<String>();  
822 -  
823 - /// close stream = onClose method, not dispose.  
824 - @override  
825 - void onClose() {  
826 - user.close();  
827 - name.close();  
828 - super.onClose();  
829 - }  
830 -}  
831 -```  
832 -  
833 -Ciclo de vida del Controller:  
834 -  
835 -- onInit() donde se crea.  
836 -- onClose() donde está cerrado para cualquier tipo de modificación en preparación para ser removido.  
837 -- deleted: no tiene acceso a esta API porque literalmente el Controller está eliminando de la memoria, sin dejar rastro (literal).  
838 -  
839 -### Otras formas de usarlo  
840 -  
841 -Puede usar la instancia de Controller directamente en el value de GetBuilder:  
842 -  
843 -```dart  
844 -GetBuilder<Controller>(  
845 - init: Controller(),  
846 - builder: (value) => Text(  
847 - '${value.counter}', //here  
848 - ),  
849 -),  
850 -```  
851 -  
852 -También puede necesitar una instancia de su Controller fuera de su GetBuilder, y puede usar estos enfoques para lograr esto:  
853 -  
854 -```dart  
855 -class Controller extends GETXController {  
856 - static Controller get to => Get.find();  
857 -[...]  
858 -}  
859 -// on you view:  
860 -GetBuilder<Controller>(  
861 - init: Controller(), // use it only first time on each controller  
862 - builder: (_) => Text(  
863 - '${Controller.to.counter}', //here  
864 - )  
865 -),  
866 -```  
867 -  
868 -o  
869 -  
870 -```dart  
871 -class Controller extends GETXController {  
872 - // static Controller get to => Get.find(); // with no static get  
873 -[...]  
874 -}  
875 -// on stateful/stateless class  
876 -GetBuilder<Controller>(  
877 - init: Controller(), // use it only first time on each controller  
878 - builder: (_) => Text(  
879 - '${Get.find<Controller>().counter}', //here  
880 - ),  
881 -),  
882 -```  
883 -  
884 -- Puede utilizar enfoques "no canónicos" para hacer esto. Si está utilizando algún otro gestor de dependencias, como get_it, modular, etc., y solo desea entregar la instancia de Controller, puede hacer esto:  
885 -  
886 -```dart  
887 -Controller controller = Controller();  
888 -[...]  
889 -GetBuilder<Controller>(  
890 - init: controller, //here  
891 - builder: (_) => Text(  
892 - '${controller.counter}', // here  
893 - ),  
894 -),  
895 -```  
896 -  
897 -### ID únicos  
898 -Si desea refinar el control de actualización de widgets con GetBuilder, puede asignarles ID únicos:  
899 -  
900 -```dart  
901 -GetBuilder<Controller>(  
902 - id: 'text'  
903 - init: Controller(), // use it only first time on each controller  
904 - builder: (_) => Text(  
905 - '${Get.find<Controller>().counter}', //here  
906 - ),  
907 -),  
908 -```  
909 -  
910 -Y actualízalo de esta forma:  
911 -  
912 -```dart  
913 -update(['text']);  
914 -```  
915 -  
916 -También puede imponer condiciones para la actualización:  
917 -  
918 -```dart  
919 -update(['text'], counter < 10);  
920 -```  
921 -  
922 -GetX hace esto automáticamente y solo reconstruye el widget que usa la variable exacta que se modificó, si cambia una variable a la misma que la anterior y eso no implica un cambio de estado, GetX no reconstruirá el widget para ahorrar memoria y ciclos de CPU (ej. si se muestra 3 en pantalla y la variable cambia a 3 nuevamente, en la mayoría de los gestores de estados, esto provocará una nueva reconstrucción, pero con GetX el widget solo se reconstruirá si efectivamente su estado ha sido modificado).  
923 -  
924 -## Reactivo STATE_MANAGER  
925 -  
926 -La programación reactiva puede alienar a muchas personas porque se dice que es complicada. GetX convierte la programación reactiva en algo tan simple que puede ser aprendido y utilizado por aquellos que comenzaron en ese mismo momento en Flutter. No, no necesitará crear StreamControllers. Tampoco necesitará crear un StreamBuilder para cada variable. No necesitará crear una clase para cada estado. No necesitará crear un get para un valor inicial. La programación reactiva con GetX es tan fácil como usar setState (¡o incluso más fácil!).  
927 -  
928 -Imaginemos que tiene una variable "name" y desea que cada vez que la modifique, todos los widgets que la usan cambien automáticamente.  
929 -  
930 -Ej. esta es tu variable "name":  
931 -  
932 -```dart  
933 -var name = 'Jonatas Borges';  
934 -```  
935 -  
936 -Para que sea observable, solo necesita agregar ".obs" al final:  
937 -  
938 -```dart  
939 -var name = 'Jonatas Borges'.obs;  
940 -```  
941 -  
942 -Esto raya en lo absurdo cuando se trata de practicidad. ¿Qué hicimos, debajo del capó? Creamos un stream de Strings, asignamos el valor inicial "Jonatas Borges", advertimos a todos los widgets que usan "Jonatas Borges" que ahora pertenecen a esta variable, y cuando se modifica, ellos también lo harán. Esta es la magia de GetX, que solo Dart nos permite hacer.  
943 -  
944 -De acuerdo, pero como sabemos, un widget solo se puede modificar si está dentro de una función, porque las clases estáticas no tienen el poder de "auto-change". Tendrá que crear un StreamBuilder, suscribirse para escuchar esta variable y crear una "cascada" de StreamBuilder si desea cambiar multiples variables en el mismo scope, ¿verdad?  
945 -No, no necesitas un StreamBuilder, pero tienes razón sobre las clases estáticas.  
946 -  
947 -Bueno, en la vista, generalmente tenemos mucho boilerplate cuando queremos cambiar un widget específico. Con GetX también puedes olvidarte de esto. ¿StreamBuilder? ¿initialValue? ¿builder? No, solo necesitas jugar con esta variable dentro de un widget Obx.  
948 -  
949 -```dart  
950 -Obx(() => Text (controller.name));  
951 -```  
952 -  
953 -¿Qué necesitas memorizar? "Obx(() =>"  
954 -  
955 -Simplemente está pasando ese widget a través de una función de flecha en un Obx. Obx es inteligente, y solo se cambiará si se modifica el valor de "name". Si el nombre es "John" y usted lo cambia "John", no tendrá ningún cambio en la pantalla, y Obx simplemente ignorará este cambio y no reconstruirá ningún widget, para ahorrar recursos. ¿No es increíble?  
956 -  
957 -¿Qué pasa si tengo 5 variables observables dentro de un Obx? Se actualizará cuando se modifique alguna de ellos. Y si tengo 30 variables en una clase, cuando actualizo una, ¿actualizará todas las variables que están en esa clase? No, solo el widget específico que usa esa variable. Y si ametrallo mi variable observable mil millones de veces con el mismo valor, ¿me congelaré en la pantalla para reconstrucciones innecesarias? No, GetX solo actualiza la pantalla cuando la variable cambia en la pantalla, si la pantalla sigue siendo la misma, no reconstruirá nada.  
958 -  
959 -### Ventajas  
960 -  
961 -GetBuilder está dirigido precisamente al control de múltiples estados. Imagine que agregó 30 productos a un carrito, hace clic en eliminar uno, al mismo tiempo que se actualiza la lista, se actualiza el precio y la insignia en el carrito de compras a un número menor. Este tipo de enfoque hace que GetBuilder sea superior, porque agrupa estados y los cambia todos a la vez sin ninguna "lógica computacional" para eso. GetBuilder se creó con este tipo de situación en mente, ya que para un cambio de estado efímero, puede usar setState y no necesitaría un gestor de estado. Sin embargo, hay situaciones en las que solo desea que el widget donde una determinada variable ha sido modificada sea reconstruida, y esto es lo que GetX hace con un dominio nunca antes visto.  
962 -  
963 -De esa manera, si desea un controlador individual, puede asignar un ID o usar GetX. Esto depende de usted, recordando que cuantos más widgets "individuales" tenga, más se destacará el rendimiento de GetX, mientras que el rendimiento de GetBuilder debería ser superior cuando haya un cambio múltiple de estado.  
964 -  
965 -Puede usar ambos en cualquier situación, pero si desea ajustar su aplicación al máximo rendimiento posible, diría que:  
966 -- si sus variables se cambian en diferentes momentos, use GetX, porque no hay competencia para ello cuando el tema es para reconstruir solo lo que es necesario,  
967 -- si no necesita ID únicos, porque todas sus variables cambiarán cuando realice una acción, use GetBuilder, porque es un simple actualizador de estado en bloques, hecho en unas pocas líneas de código, para que haga exactamente lo que promete hacer: actualizar el estado en bloques. No hay forma de comparar RAM, CPU o cualquier otra cosa, desde un gestor de estado gigante a un simple StatefulWidget (como GetBuilder) que se actualiza cuando se llama a update(). Se hizo de una manera simple, para involucrar la menor lógica computacional, para cumplir con un solo propósito y consumiendo la menor cantidad de recursos posibles.  
968 -  
969 -Si quieres un poderoso gestor de estado, puedes ir sin temor a GetX. No funciona con variables, pero fluye, todo lo que contiene son streams bajo el capó. Puede usar rxDart junto con él, porque todo es streams, puede escuchar el evento de cada "variable", porque todo en él es streams, es literalmente BLoC, más fácil que MobX, y sin generador de código o decoraciones.  
970 -  
971 -Si quieres poder, GetX te ofrece el gestor de estado más avanzado que puedas tener.  
972 -  
973 -GetX fue construido 100% basado en Streams, y le brinda toda la potencia de fuego que BLoC le brindó, con una instalación más fácil que al de MobX.  
974 -  
975 -Sin decoraciones, puede convertir cualquier cosa en Observable con solo un ".obs".  
976 -  
977 -Máximo rendimiento: además de tener un algoritmo inteligente para una reconstrucción mínima, GetX utiliza comparadores para asegurarse de que el estado realmente haya cambiado. Si experimenta algún error en su aplicación y envía un cambio de estado duplicado, GetX se asegurará de que su aplicación no se colapse.  
978 -  
979 -El estado solo cambia si los valores son modificados. Esa es la principal diferencia entre GetX y usar Computed de MobX. Al unir dos observables, cuando se cambia uno, la audiencia de ese observable cambiará. Con GetX, si une dos variables (lo cual sería innecesario), GetX (similar a Observer) solo cambiará si implica un cambio de estado real.  
980 -  
981 -### Uso  
982 -  
983 -Tienes 3 formas de convertir una variable en observable.  
984 -  
985 -El primero es usar Rx{Type}.  
986 -  
987 -```dart  
988 -var count = RxString();  
989 -```  
990 -  
991 -El segundo es usar Rx y escribirlo con `Rx<Type>`  
992 -  
993 -```dart  
994 -var count = Rx<String>();  
995 -```  
996 -  
997 -El tercer enfoque, más práctico, fácil e increíble, es simplemente agregar un .obs a su variable.  
998 -  
999 -```dart  
1000 -var count = 0.obs;  
1001 -  
1002 -// or Rxint count = 0.obs;  
1003 -// or Rx<int> count = 0.obs;  
1004 -```  
1005 -  
1006 -Como sabemos, Dart ahora se dirige hacia el null safety. Con eso es una buena idea, de ahora en adelante, que comience a usar sus variables siempre con un valor inicial.  
1007 -  
1008 -Transformar una variable en observable con un valor inicial con GetX es el enfoque más simple y práctico que existe actualmente en Flutter. Literalmente agregará un ".obs" al final de su variable, y eso es todo, lo ha hecho observable, y su valor será el valor inicial, ¡esto es fantástico!  
1009 -  
1010 -Puede agregar variables, y si desea escribir un widget que le permita obtener su controlador dentro, solo necesita usar el widget GetX en lugar de Obx  
1011 -  
1012 -```dart  
1013 -final count1 = 0.obs;  
1014 -final count2 = 0.obs;  
1015 -int get sum => count1.value + count2.value;  
1016 -```  
1017 -  
1018 -```dart  
1019 -GetX<Controller>(  
1020 - builder: (value) {  
1021 - print("count 1 rebuild");  
1022 - return Text('${value.count1.value}');  
1023 - },  
1024 -),  
1025 -GetX<Controller>(  
1026 - builder: (_) {  
1027 - print("count 2 rebuild");  
1028 - return Text('${_.count2.value}');  
1029 - },  
1030 -),  
1031 -GetX<Controller>(  
1032 - builder: (_) {  
1033 - print("count 3 rebuild");  
1034 - return Text('${_.sum}');  
1035 - },  
1036 -),  
1037 -```  
1038 -  
1039 -Si incrementamos el número de counter1, solo se reconstruyen el counter1 y el counter3, porque el counter1 ahora tiene un valor de 1 y 1 + 0 = 1, cambiando el valor de la suma.  
1040 -  
1041 -Si cambiamos el counter2, solo se reconstruyen el counter2 y 3, porque el valor de 2 ha cambiado y el resultado de la suma ahora es 2.  
1042 -  
1043 -Si agregamos el número 1 para counter1, que ya contiene 1, no se reconstruye ningún widget. Si agregamos un valor de 1 para el counter1 y un valor de 2 para el counter2, solo se reconstruirán 2 y 3, porque GetX además de cambiar solo lo que es necesario, evita la duplicación de eventos.  
1044 -  
1045 -- NOTA: Por defecto, el primer evento permitirá la reconstrucción incluso si es igual. Creamos este comportamiento debido a variables dualistas, como Boolean.  
1046 -  
1047 -Imaginemos que hiciste esto:  
1048 -  
1049 -```dart  
1050 -var isLogged = false.obs;  
1051 -```  
1052 -  
1053 -y luego verifica si un usuario ha iniciado sesión para activar un evento en "ever".  
1054 -  
1055 -```dart  
1056 -onInit(){  
1057 - ever(isLogged, fireRoute);  
1058 - isLogged.value = await Preferences.hasToken();  
1059 -}  
1060 -  
1061 -fireRoute(logged) {  
1062 - if (logged) {  
1063 - Get.off(Home());  
1064 - } else {  
1065 - Get.off(Login());  
1066 - }  
1067 -}  
1068 -```  
1069 -  
1070 -si hasToken fuera falso, no habría cambios en isLogged, por lo que nunca se llamaría. Para evitar este tipo de comportamiento, el primer cambio a un observable siempre desencadenará un evento, incluso si es el mismo.  
1071 -  
1072 -Puede eliminar este comportamiento si lo desea, utilizando:  
1073 -`isLogged.firstRebuild = false;`  
1074 -  
1075 -Además, GetX proporciona control de estado refinado. Puede condicionar un evento (como agregar un objeto a una lista), en una determinada condición:  
1076 -  
1077 -```dart  
1078 -list.addIf(item < limit, item);  
1079 -```  
1080 -  
1081 -Sin decoraciones, sin un generador de código, sin complicaciones, GetX cambiará la forma en que administra sus estados en Flutter, y eso no es una promesa, ¡es una certeza!  
1082 -  
1083 -¿Conoces el counter de Flutter? Su clase de controlador podría verse así:  
1084 -  
1085 -```dart  
1086 -class CountCtl extends GetxController {  
1087 - final count = 0.obs;  
1088 -}  
1089 -```  
1090 -Con un simple:  
1091 -  
1092 -```dart  
1093 -ctl.count.value++  
1094 -```  
1095 -  
1096 -Puede actualizar la variable de contador en su IU, independientemente de dónde esté almacenada.  
1097 -  
1098 -### Donde se pueden usar .obs  
1099 -  
1100 -Puedes transformar cualquier cosa en obs:  
1101 -  
1102 -```dart  
1103 -class RxUser {  
1104 - final name = "Camila".obs;  
1105 - final age = 18.obs;  
1106 -}  
1107 -  
1108 -class User {  
1109 - User({String name, int age});  
1110 - final rx = RxUser();  
1111 -  
1112 - String get name => rx.name.value;  
1113 - set name(String value) => rx.name.value = value;  
1114 -  
1115 - int get age => rx.age.value;  
1116 - set age(int value) => rx.age.value = value;  
1117 -}  
1118 -```  
1119 -  
1120 -```dart  
1121 -void main() {  
1122 - final user = User();  
1123 - print(user.name);  
1124 - user.age = 23;  
1125 - user.rx.age.listen((int age) => print(age));  
1126 - user.age = 24;  
1127 - user.age = 25;  
1128 -}  
1129 -___________  
1130 -out:  
1131 -Camila  
1132 -23  
1133 -24  
1134 -25  
1135 -```  
1136 -  
1137 -### Nota sobre listas  
1138 -  
1139 -Trabajar con listas usando GetX es lo mejor y lo más divertido del mundo. Son completamente observables como lo son los objetos dentro de él. De esa manera, si agrega un valor a una lista, reconstruirá automáticamente los widgets que lo usan.  
1140 -  
1141 -Tampoco necesita usar ".value" con las listas, la increíble api de Dart nos permitió eliminar eso, los tipos primitivos desafortunados como String e int no se pueden extender, haciendo que el uso de .value sea obligatorio, pero eso no será un problema si trabajas con gets y setters para estos.  
1142 -  
1143 -```dart  
1144 -final list = List<User>().obs;  
1145 -```  
1146 -  
1147 -```dart  
1148 -ListView.builder (  
1149 - itemCount: list.lenght  
1150 -)  
1151 -```  
1152 -  
1153 -No tiene que trabajar con Sets si no lo desea. puede usar la api "assign" y "assignAll".  
1154 -  
1155 -La API "assign" borrará su lista y agregará un solo objeto, con el que quiere comenzar allí.  
1156 -  
1157 -La API "assignAll" borrará la lista existente y agregará cualquier objeto iterable que le inyecte.  
1158 -  
1159 -### ¿Por qué tengo que usar .value?  
1160 -  
1161 -Podríamos eliminar la obligación de usar 'value' para String e int con una simple decoración y generador de código, pero el propósito de esta biblioteca es, precisamente, no necesitar ninguna dependencia externa. Ofrecer un entorno listo para la programación, que incluya lo esencial (gestión de rutas, dependencias y estados), de una manera simple, ligera y de gran rendimiento sin necesidad de ningún otro paquete externo. Literalmente, agrega GetX a su pubspec y puede comenzar a programar.  
1162 -  
1163 -Todas las soluciones incluidas por defecto, desde gestión de rutas a gestión de estádo, apuntan a la facilidad, la productividad y el rendimiento. El peso total de esta biblioteca es menor que el de un solo gestor de estado, aunque es una solución completa, y eso es lo que debe comprender.  
1164 -  
1165 -Si le molesta el ".value" y, como además si se trata de un generador de código, MobX ya es una gran alternativa, puede simplemente usarlo junto con GetX.  
1166 -  
1167 -Para aquellos que desean agregar una sola dependencia en pubspec y comenzar a programar sin preocuparse de que la versión de un paquete sea incompatible con otra, o si el error de una actualización de estado proviene de gestor de estado o dependencia, o aún, no quieren preocuparse por la disponibilidad de controladores, ya sea literalmente "solo programación", GetX es simplemente perfecto.  
1168 -  
1169 -Si no tiene ningún problema con el generador de código de MobX, o no tiene ningún problema con el boilerplate de BLoC, simplemente puede usar GetX para las rutas y olvidar que incluye un gestor de estado. GetX, SEM y RSM nacieron por necesidad, mi empresa tenía un proyecto con más de 90 controladores, y el generador de código tardó más de 30 minutos en completar sus tareas después de un Flutter Clean en una máquina razonablemente buena. Si su proyecto tiene 5, 10, 15 controladores, cualquier gestor de estado te vendrá bien. Si tiene un proyecto absurdamente grande y el generador de código es un problema para usted, se le ha otorgado esta solución.  
1170 -  
1171 -Obviamente, si alguien quiere contribuir al proyecto y crear un generador de código, o algo similar, lo añadiré a este archivo como una alternativa, mi necesidad no es la necesidad de todos los desarrolladores, pero lo que ahora digo es que hay buenas soluciones que ya hacen eso, como MobX.  
1172 -  
1173 -### Obx()  
1174 -  
1175 -El Typing en GetX usando Bindings es innecesario. Puede usar el widget Obx (en lugar de GetX), que solo recibe la función anónima que crea un widget.  
1176 -  
1177 -Obviamente, si no usa un tipo, necesitará tener una instancia de su controlador para usar las variables, o usar `Get.find <Controller>()` .value o Controller.to.value para recuperar el valor.  
1178 -  
1179 -### Workers:  
1180 -  
1181 -Los workers lo ayudarán, activando callbacks específicos cuando ocurra un evento.  
1182 -  
1183 -```dart  
1184 -/// Called every time the variable $_ is changed  
1185 -ever(count1, (_) => print("$_ has been changed"));  
1186 -  
1187 -/// Called only first time the variable $_ is changed  
1188 -once(count1, (_) => print("$_ was changed once"));  
1189 -  
1190 -/// Anti DDos - Called every time the user stops typing for 1 second, for example.  
1191 -debounce(count1, (_) => print("debouce$_"), time: Duration(seconds: 1));  
1192 -  
1193 -/// Ignore all changes within 1 second.  
1194 -interval(count1, (_) => print("interval $_"), time: Duration(seconds: 1));  
1195 -```  
1196 -  
1197 -- ever: se llama cada vez que se cambia su variable. Eso es.  
1198 -  
1199 -- once: se llama solo la primera vez que se ha cambiado la variable.  
1200 -  
1201 -- debounce: es muy útil en las funciones de búsqueda, donde solo desea que se llame a la API cuando el usuario termina de escribir. Si el usuario escribe "JONNY", tendrá 5 búsquedas en las API, por la letra J, O, N, N e Y. Con GetX esto no sucede, porque tendrá un worker "debounce" que solo se activará al final de la escritura.  
1202 -  
1203 -- interval: es diferente del debouce. Con debouce si el usuario realiza 1000 cambios en una variable dentro de 1 segundo, enviará solo el último después del timer estipulado (el valor predeterminado es 800 milisegundos). En cambio, el interval ignorará todas las acciones del usuario durante el período estipulado. Si envía eventos durante 1 minuto, 1000 por segundo, la función antirrebote solo le enviará el último, cuando el usuario deje de enviar eventos. Interval entregará eventos cada segundo, y si se establece en 3 segundos, entregará 20 eventos ese minuto. Esto se recomienda para evitar abusos, en funciones en las que el usuario puede hacer clic rápidamente en algo y obtener alguna ventaja (imagine que el usuario puede ganar monedas haciendo clic en algo, si hace clic 300 veces en el mismo minuto, tendría 300 monedas, usando el interval, puede establecer un time frame de 3 segundos, e incluso luego hacer clic 300 o mil veces, el máximo que obtendría en 1 minuto sería 20 monedas, haciendo clic 300 o 1 millón de veces). El debouce es adecuado para anti-DDos, para funciones como la búsqueda donde cada cambio en onChange provocaría una consulta en su API. Debounce esperará a que el usuario deje de escribir el nombre para realizar la solicitud. Si se usara en el escenario de monedas mencionado anteriormente, el usuario solo ganaría 1 moneda, ya que solo se ejecuta cuando el usuario "hace una pausa" durante el tiempo establecido.  
1204 -  
1205 -## Mezclando los dos State Managers  
1206 -  
1207 -Algunas personas abrieron una feature request, ya que querían usar solo un tipo de variable reactiva, y la otra mecánica, y necesitaban insertar un Obx en un GetBuilder para esto. Pensando en ello, se creó MixinBuilder. Permite cambios reactivos cambiando las variables ".obs" y actualizaciones mecánicas a través de update(). Sin embargo, de los 4 widgets, es el que consume más recursos, ya que además de tener una suscripción para recibir eventos de cambio de sus hijos, se suscribe al método update de su controlador.  
1208 -  
1209 -Extender GetxController es importante, ya que tienen ciclos de vida y pueden "iniciar" y "finalizar" eventos en sus métodos onInit() y onClose(). Puede usar cualquier clase para esto, pero le recomiendo que use la clase GetxController para colocar sus variables, sean observables o no.  
1210 -  
1211 -## GetBuilder vs GetX vs Obx vs MixinBuilder  
1212 -  
1213 -En una década trabajando con programación pude aprender algunas lecciones valiosas.  
1214 -  
1215 -Mi primer contacto con la programación reactiva fue tan "guau, esto es increíble" y, de hecho, la programación reactiva es increíble.  
1216 -  
1217 -Sin embargo, no es adecuado para todas las situaciones. A menudo, todo lo que necesita es cambiar el estado de 2 o 3 widgets al mismo tiempo, o un cambio de estado efímero, en cuyo caso la programación reactiva no es mala, pero no es apropiada.  
1218 -  
1219 -La programación reactiva tiene un mayor consumo de RAM que se puede compensar con el workflow individual, lo que garantizará que solo se reconstruya un widget y cuando sea necesario, pero crear una lista con 80 objetos, cada uno con varios streams no es una buena idea. Abra el dart inspector y compruebe cuánto consume un StreamBuilder, y comprenderá lo que estoy tratando de decirle.  
1220 -  
1221 -Con eso en mente, creé el Simple State Manager. Es simple, y eso es exactamente lo que debe exigirle: actualizar el estado en bloques de una manera simple y de la manera más económica.  
1222 -  
1223 -GetBuilder es muy económico en RAM, y es difícil que haya un enfoque más económico que él (al menos no puedo imaginar uno, si existe, háganoslo saber).  
1224 -  
1225 -Sin embargo, GetBuilder sigue siendo un gestor de estado mecánico, debe llamar a update() al igual que necesitaría llamar a notifyListeners() con Provider.  
1226 -  
1227 -Hay otras situaciones, en las que la programación reactiva es realmente interesante, y no trabajar con ella es lo mismo que reinventar la rueda. Con eso en mente, GetX fue creado para proporcionar todo lo más moderno y avanzado en un gestor de estado. Actualiza solo lo necesario y solo si es necesario, si tiene un error y envía 300 cambios de estado simultáneamente, GetX lo filtrará y actualizará la pantalla solo si el estado realmente fue modificado.  
1228 -  
1229 -GetX es aún más económico que cualquier otro gestor de estado reactivo, pero consume un poco más de RAM que GetBuilder. Pensando en ello y con el objetivo de maximizar el consumo de recursos es que se creó Obx. A diferencia de GetX y GetBuilder, no podrá inicializar un controlador dentro de un Obx, es solo un Widget con una stream suscription que recibe eventos de cambio de sus children, eso es todo. Es más económico que GetX, pero pierde con GetBuilder, lo que era de esperar, ya que es reactivo, y GetBuilder tiene el enfoque más simplista que existe, de almacenar el código hash de un widget y su StateSetter. Con Obx no necesita escribir su tipo de controlador, y puede escuchar el cambio desde varios controladores diferentes, pero debe inicializarse antes, ya sea utilizando el enfoque de ejemplo al comienzo de este archivo o utilizando la clase Bindings.  
1230 -  
1231 -# Gestión de dependencias  
1232 -  
1233 -## Simple Instance Manager  
1234 -  
1235 -- Nota: si está utilizando el gestor de estado de GetX, no tiene que preocuparse por esto, solo lea para obtener información, pero preste más atención a la API de bindings, que hará todo esto automáticamente por usted.  
1236 -  
1237 -¿Ya estás utilizando GetX y quieres que tu proyecto sea lo más ágil posible? GetX tiene un gestor de dependencias simple y poderoso que le permite recuperar la misma clase que su BLoC o Controller con solo una líneas de código, sin contexto de Provider, sin inheritedWidget:  
1238 -  
1239 -```dart  
1240 -Controller controller = Get.put(Controller()); // Rather Controller controller = Controller();  
1241 -```  
1242 -  
1243 -En lugar de crear una instancia de su clase dentro de la clase que está utilizando, la está creando dentro de la instancia GetX, que la hará disponible en toda su aplicación. Entonces puede usar su Controller (o BLoC) normalmente.  
1244 -  
1245 -```dart  
1246 -controller.fetchApi();  
1247 -```  
1248 -  
1249 -Imagine que ha navegado a través de numerosas rutas y necesita datos que quedaron en su controlador, necesitaría un gestor de estado combinado con Providere o Get_it, ¿correcto? No con GetX. Solo necesita pedirle a GetX que "encuentre" su controlador, no necesita dependencias adicionales:  
1250 -  
1251 -```dart  
1252 -Controller controller = Get.find();  
1253 -//Yes, it looks like Magic, Get will find your controller, and will deliver it to you. You can have 1 million controllers instantiated, Get will always give you the right controller.  
1254 -```  
1255 -  
1256 -Y luego podrá recuperar los datos de su controlador que se obtuvieron allí:  
1257 -  
1258 -```dart  
1259 -Text(controller.textFromApi);  
1260 -```  
1261 -  
1262 -¿Buscando lazy loading? Puede declarar todos sus controladores, y se llamará solo cuando alguien lo necesite. Puedes hacer esto con:  
1263 -  
1264 -```dart  
1265 -Get.lazyPut<Service>(()=> ApiMock());  
1266 -/// ApiMock will only be called when someone uses Get.find<Service> for the first time  
1267 -```  
1268 -  
1269 -Si desea registrar una instancia asincrónica, puede usar Get.putAsync.  
1270 -  
1271 -```dart  
1272 -Get.putAsync<SharedPreferences>(() async {  
1273 - final prefs = await SharedPreferences.getInstance();  
1274 - await prefs.setInt('counter', 12345);  
1275 - return prefs;  
1276 -});  
1277 -```  
1278 -  
1279 -uso:  
1280 -  
1281 -```dart  
1282 - int count = Get.find<SharedPreferences>().getInt('counter');  
1283 - print(count);  
1284 - // out: 12345  
1285 -}  
1286 -```  
1287 -  
1288 -Para eliminar una instancia de GetX:  
1289 -  
1290 -```dart  
1291 -Get.delete<Controller>();  
1292 -```  
1293 -  
1294 -## Bindings  
1295 -  
1296 -Una de las grandes diferencias de este paquete, tal vez, es la posibilidad de una integración completa de las rutas, gestor de estado y dependencias.  
1297 -  
1298 -Cuando se elimina una ruta del stack, todos los controladores, variables e instancias de objetos relacionados con ella se eliminan de la memoria. Si está utilizando stream o timers, se cerrarán automáticamente y no tendrá que preocuparse por nada de eso.  
1299 -  
1300 -En la versión 2.10 GetX se implementó por completo la API de bindings.  
1301 -  
1302 -Ahora ya no necesita usar el método init. Ni siquiera tiene que escribir sus controladores si no lo desea. Puede iniciar sus controladores y servicios en un lugar apropiado para eso.  
1303 -  
1304 -La clase Binding es una clase que desacoplará la inyección de dependencia, al tiempo que vinculará rutas con el gestor de estado y el gestor de dependencias.  
1305 -  
1306 -Esto permite conocer qué pantalla se muestra cuando se utiliza un controlador en particular y saber dónde y cómo descartarlo.  
1307 -  
1308 -Además, la clase Binding le permitirá tener el control de configuración SmartManager. Puede configurar las dependencias que se organizarán al eliminar una ruta de la pila, o cuando el widget que lo usó se presenta, o ninguno de los dos. Tendrá una gestión inteligente de dependencias que funcione para usted, pero aun así, puede configurarla como desee.  
1309 -  
1310 -### Cómo utilizar  
1311 -  
1312 -- Crea una clase e implementa Binding  
1313 -  
1314 -```dart  
1315 -class HomeBinding implements Bindings{  
1316 -```  
1317 -  
1318 -Su IDE le pedirá automáticamente que anule el método de "dependencies", y solo necesita hacer clic en la lámpara, anular el método e insertar todas las clases que va a utilizar en esa ruta:  
1319 -  
1320 -```dart  
1321 -class HomeBinding implements Bindings{  
1322 - @override  
1323 - void dependencies() {  
1324 - Get.lazyPut<ControllerX>(() => ControllerX());  
1325 - Get.lazyPut<Service>(()=> Api());  
1326 - }  
1327 -}  
1328 -```  
1329 -  
1330 -Ahora solo necesita informar su ruta, que utilizará ese binding para establecer la conexión entre el gestor de rutas, las dependencias y los estados.  
1331 -  
1332 -- Uso de rutas nombradas:  
1333 -  
1334 -```dart  
1335 -namedRoutes: {  
1336 - '/': GetRoute(Home(), binding: HomeBinding())  
1337 -}  
1338 -```  
1339 -  
1340 -- Usando rutas normales:  
1341 -  
1342 -```dart  
1343 -Get.to(Home(), binding: HomeBinding());  
1344 -```  
1345 -  
1346 -Allí, ya no tiene que preocuparse por la administración de memoria de su aplicación, GetX lo hará por usted.  
1347 -  
1348 -La clase Binding se llama cuando se llama una ruta, puede crear un initialBinding en su GetMaterialApp para insertar todas las dependencias que se crearán.  
1349 -  
1350 -```dart  
1351 -GetMaterialApp(  
1352 - initialBinding: SampleBind(),  
1353 - home: Home(),  
1354 -);  
1355 -```  
1356 -  
1357 -## SmartManagement  
1358 -  
1359 -Siempre prefiera usar SmartManagement estándar (full), no necesita configurar nada para eso, GetX ya se lo proporciona de forma predeterminada. Seguramente eliminará todos los controladores en desuso de la memoria, ya que su control refinado elimina la dependencia, incluso si se produce un error y un widget que lo utiliza no se elimina correctamente.  
1360 -  
1361 -El modo "full" también es lo suficientemente seguro como para usarlo con StatelessWidget, ya que tiene numerosos callbacks de seguridad que evitarán que un controlador permanezca en la memoria si ningún widget lo está utilizando, y los disposers no son importante aquí. Sin embargo, si le molesta el comportamiento predeterminado, o simplemente no quiere que suceda, GetX ofrece otras opciones más indulgentes para la administración inteligente de la memoria, como SmartManagement.onlyBuilders, que dependerá de la eliminación efectiva de los widgets que estén usando el controller para eliminarlo, y puede evitar que se implemente un controlador usando "autoRemove: false" en su GetBuilder/GetX.  
1362 -  
1363 -Con esta opción, solo se eliminarán los controladores iniciados en "init:" o cargados en un enlace con "Get.lazyPut"; si usa Get.put o cualquier otro enfoque, SmartManagement no tendrá permisos para excluir esta dependencia.  
1364 -  
1365 -Con el comportamiento predeterminado, incluso los widgets instanciados con "Get.put" se eliminarán, a diferencia de SmartManagement.onlyBuilders.  
1366 -  
1367 -SmartManagement.keepFactory es como SmartManagement.full, con una diferencia. SmartManagement.full purga los factories de las premises, de modo que Get.lazyPut() solo podrá llamarse una vez y su factory y sus referencias se autodestruirán. SmartManagement.keepFactory eliminará sus dependencias cuando sea necesario, sin embargo, mantendrá la "forma" de estas, para hacer una igual si necesita una instancia de eso nuevamente.  
1368 -  
1369 -En lugar de usar SmartManagement.keepFactory, puede usar Bindings.  
1370 -  
1371 -Bindings crea factories transitorios, que se crean en el momento en que hace clic para ir a otra pantalla, y se destruirán tan pronto como ocurra la animación de cambio de pantalla. Es tan poco tiempo que el analizador ni siquiera podrá registrarlo. Cuando navegue de nuevo a esta pantalla, se llamará a una nueva factory temporal, por lo que es preferible usar SmartManagement.keepFactory, pero si no desea crear enlaces o desea mantener todas sus dependencias en el mismo enlace, sin duda te ayudará. Las factories ocupan poca memoria, no tienen instancias, sino una función con la "forma" de esa clase que desea. Esto es muy poco, pero dado que el propósito de esta lib es obtener el máximo rendimiento posible utilizando los recursos mínimos, GetX elimina incluso las factories por defecto. Use el que sea más conveniente para usted.  
1372 -  
1373 -- NOTA: NO USE SmartManagement.keepFactory si está utilizando bindings múltiples. Fue diseñado para usarse sin bindings, o con uno único vinculado en el binding inicial de GetMaterialApp.  
1374 -  
1375 -- NOTA2: El uso de bindings es completamente opcional, puede usar Get.put() y Get.find() en clases que usan un controlador dado sin ningún problema. 196 +### Explicación completa
1376 197
1377 -Sin embargo, si trabaja con Servicios o cualquier otra abstracción, le recomiendo usar binding para una organización más grande. 198 +**Vea una explicación más detallada de la Gestión de dependencias [aquí](./docs/es_ES/dependency_management.md).**
1378 199
1379 # Utils 200 # Utils
1380 201
@@ -1492,7 +313,7 @@ Antes: NumX ahora: RxNum @@ -1492,7 +313,7 @@ Antes: NumX ahora: RxNum
1492 313
1493 Antes: RxDouble ahora: RxDouble 314 Antes: RxDouble ahora: RxDouble
1494 315
1495 -RxController y GetBuilder ahora se han fusionado, ya no necesita memorizar qué controlador desea usar, solo use GETXController, funcionará para gestión de estádo simple y también para reactivo. 316 +RxController y GetBuilder ahora se han fusionado, ya no necesita memorizar qué controlador desea usar, solo use GetXController, funcionará para gestión de estádo simple y también para reactivo.
1496 317
1497 2- Rutas Nombradas 318 2- Rutas Nombradas
1498 319
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 2
3 *Languages: English (this file), [Brazilian Portuguese](README.pt-br.md), [Spanish](README-es.md).* 3 *Languages: English (this file), [Brazilian Portuguese](README.pt-br.md), [Spanish](README-es.md).*
4 4
5 -[![pub package](https://img.shields.io/pub/v/get.svg?label=get&color=blue)](https://pub.dev/packages/get) 5 +[![pub package](https://img.shields.io/pub/v/get.svg?label=get&color=blue)](https://pub.dev/packages/get)
6 ![building](https://github.com/jonataslaw/get/workflows/build/badge.svg) 6 ![building](https://github.com/jonataslaw/get/workflows/build/badge.svg)
7 [![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) 7 [![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)
8 <a href="https://github.com/Solido/awesome-flutter"> 8 <a href="https://github.com/Solido/awesome-flutter">
@@ -10,22 +10,49 @@ @@ -10,22 +10,49 @@
10 </a> 10 </a>
11 <a href="https://www.buymeacoffee.com/jonataslaw" target="_blank"><img src="https://i.imgur.com/aV6DDA7.png" alt="Buy Me A Coffee" 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> 11 <a href="https://www.buymeacoffee.com/jonataslaw" target="_blank"><img src="https://i.imgur.com/aV6DDA7.png" alt="Buy Me A Coffee" 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>
12 12
  13 +<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
  14 +[![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-)
  15 +<!-- ALL-CONTRIBUTORS-BADGE:END -->
  16 +- [About Get](#about-get)
  17 +- [The Three pillars](#the-three-pillars)
  18 + - [State management](#state-management)
  19 + - [In-depth explanation](#in-depth-explanation)
  20 + - [Route management](#route-management)
  21 + - [In-Depth Explanation](#in-depth-explanation-1)
  22 + - [Dependency management](#dependency-management)
  23 + - [In-depth explanation](#in-depth-explanation-2)
  24 +- [How to contribute](#how-to-contribute)
  25 +- [Utils](#utils)
  26 + - [Change Theme](#change-theme)
  27 + - [Other Advanced APIs](#other-advanced-apis)
  28 + - [Optional Global Settings and Manual configurations](#optional-global-settings-and-manual-configurations)
  29 +- [Breaking changes from 2.0](#breaking-changes-from-20)
  30 +- [Why I made this package](#why-i-made-this-package)
  31 +
  32 +# About Get
13 33
14 - GetX is an extra-light and powerful solution for Flutter. It combines high performance state management, intelligent dependency injection, and route management in a quick and practical way. 34 - GetX is an extra-light and powerful solution for Flutter. It combines high performance state management, intelligent dependency injection, and route management in a quick and practical way.
15 - GetX is not for everyone, its focus is (performance) on the minimum consumption of resources ([look the benchmarks](https://github.com/jonataslaw/benchmarks)), (productivity) using an easy and pleasant syntax and (organization) allowing the total decoupling of the View from the business logic. 35 - GetX is not for everyone, its focus is (performance) on the minimum consumption of resources ([look the benchmarks](https://github.com/jonataslaw/benchmarks)), (productivity) using an easy and pleasant syntax and (organization) allowing the total decoupling of the View from the business logic.
16 - GetX will save hours of development, and will extract the maximum performance that your application can deliver, being easy for beginners, and accurate for experts. Navigate without context, open dialogs, snackbars or bottomsheets from anywhere in your code, Manage states and inject dependencies in an easy and practical way. Get is secure, stable, up-to-date, and offers a huge range of APIs that are not present on default framework. 36 - GetX will save hours of development, and will extract the maximum performance that your application can deliver, being easy for beginners, and accurate for experts. Navigate without context, open dialogs, snackbars or bottomsheets from anywhere in your code, Manage states and inject dependencies in an easy and practical way. Get is secure, stable, up-to-date, and offers a huge range of APIs that are not present on default framework.
17 -- GetX is not a blot. It has a multitude of features that allow you to start programming without worrying about anything, but each of these features are in separate containers, and are only started after use. If you only use State Management, only State Management will be compiled. If you only use routes, nothing from the state management will be compiled. You can compile the benchmark repository, and you will see that using only Get state management, the application compiled with Get has become smaller than all other applications that have only the state management of other packages, because nothing that is not used will be compiled into your code, and each GetX solution was designed to be extra lightweight. The merit here also comes from Flutter's AOT which is incredible, and manages to eliminate unused resources like no other framework does. 37 +- GetX is not a bloc. It has a multitude of features that allow you to start programming without worrying about anything, but each of these features are in separate containers, and are only started after use. If you only use State Management, only State Management will be compiled. If you only use routes, nothing from the state management will be compiled. You can compile the benchmark repository, and you will see that using only Get state management, the application compiled with Get has become smaller than all other applications that have only the state management of other packages, because nothing that is not used will be compiled into your code, and each GetX solution was designed to be extra lightweight. The merit here also comes from Flutter's AOT which is incredible, and manages to eliminate unused resources like no other framework does.
18 38
19 **GetX makes your development productive, but want to make it even more productive? Add the extension [GetX extension to VSCode](https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets) to your VSCode** 39 **GetX makes your development productive, but want to make it even more productive? Add the extension [GetX extension to VSCode](https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets) to your VSCode**
20 40
  41 +# The Three pillars
  42 +
  43 +## State management
  44 +
  45 +**See an more in-depth explanation of state management [here](./docs/en_US/state_management.md). There you will see more examples and also the differente between the simple stage manager and the reactive state manager**
21 46
22 The "counter" project created by default on new project on Flutter has over 100 lines (with comments). To show the power of Get, I will demonstrate how to make a "counter" changing the state with each click, switching between pages and sharing the state between screens, all in an organized way, separating the business logic from the view, in ONLY 26 LINES CODE INCLUDING COMMENTS. 47 The "counter" project created by default on new project on Flutter has over 100 lines (with comments). To show the power of Get, I will demonstrate how to make a "counter" changing the state with each click, switching between pages and sharing the state between screens, all in an organized way, separating the business logic from the view, in ONLY 26 LINES CODE INCLUDING COMMENTS.
23 48
24 -- Step 1: 49 +- Step 1:
25 Add "Get" before your materialApp, turning it into GetMaterialApp 50 Add "Get" before your materialApp, turning it into GetMaterialApp
  51 +
26 ```dart 52 ```dart
27 void main() => runApp(GetMaterialApp(home: Home())); 53 void main() => runApp(GetMaterialApp(home: Home()));
28 ``` 54 ```
  55 +
29 - Note: this does not modify the MaterialApp of the Flutter, GetMaterialApp is not a modified MaterialApp, it is just a pre-configured Widget, which has the default MaterialApp as a child. You can configure this manually, but it is definitely not necessary. GetMaterialApp will create routes, inject them, inject translations, inject everything you need for route navigation. If you use Get only for state management or dependency management, it is not necessary to use GetMaterialApp. GetMaterialApp is necessary for routes, snackbars, internationalization, bottomSheets, dialogs, and high-level apis related to routes and absence of context. 56 - Note: this does not modify the MaterialApp of the Flutter, GetMaterialApp is not a modified MaterialApp, it is just a pre-configured Widget, which has the default MaterialApp as a child. You can configure this manually, but it is definitely not necessary. GetMaterialApp will create routes, inject them, inject translations, inject everything you need for route navigation. If you use Get only for state management or dependency management, it is not necessary to use GetMaterialApp. GetMaterialApp is necessary for routes, snackbars, internationalization, bottomSheets, dialogs, and high-level apis related to routes and absence of context.
30 57
31 - Step 2: 58 - Step 2:
@@ -34,12 +61,14 @@ You can make any variable observable using a simple ".obs". @@ -34,12 +61,14 @@ You can make any variable observable using a simple ".obs".
34 61
35 ```dart 62 ```dart
36 class Controller extends GetxController{ 63 class Controller extends GetxController{
37 - var count = 0.obs; 64 + var count = 0.obs;
38 increment() => count.value++; 65 increment() => count.value++;
39 } 66 }
40 ``` 67 ```
  68 +
41 - Step 3: 69 - Step 3:
42 Create your View, use StatelessWidget and save some RAM, with Get you may no longer need to use StatefulWidget. 70 Create your View, use StatelessWidget and save some RAM, with Get you may no longer need to use StatefulWidget.
  71 +
43 ```dart 72 ```dart
44 class Home extends StatelessWidget { 73 class Home extends StatelessWidget {
45 74
@@ -72,69 +101,17 @@ class Other extends StatelessWidget { @@ -72,69 +101,17 @@ class Other extends StatelessWidget {
72 101
73 This is a simple project but it already makes clear how powerful Get is. As your project grows, this difference will become more significant. Get was designed to work with teams, but it makes the job of an individual developer simple. Improve your deadlines, deliver everything on time without losing performance. Get is not for everyone, but if you identified with that phrase, Get is for you! 102 This is a simple project but it already makes clear how powerful Get is. As your project grows, this difference will become more significant. Get was designed to work with teams, but it makes the job of an individual developer simple. Improve your deadlines, deliver everything on time without losing performance. Get is not for everyone, but if you identified with that phrase, Get is for you!
74 103
75 -- [Route Management](#route-management)  
76 - - [How to use?](#how-to-use)  
77 - - [Navigation without named routes](#navigation-without-named-routes)  
78 - - [Navigation with named routes](#navigation-with-named-routes)  
79 - - [Send data to named Routes:](#send-data-to-named-routes)  
80 - - [Dynamic urls links](#dynamic-urls-links)  
81 - - [Middleware](#middleware)  
82 - - [Navigation without context](#navigation-without-context)  
83 - - [SnackBars](#snackbars)  
84 - - [Dialogs](#dialogs)  
85 - - [BottomSheets](#bottomsheets)  
86 - - [Nested Navigation](#nested-navigation)  
87 -- [State Management](#state-management)  
88 - - [Simple State Manager](#simple-state-manager)  
89 - - [Advantages](#advantages)  
90 - - [Usage](#usage)  
91 - - [How it handles controllers](#how-it-handles-controllers)  
92 - - [You won't need StatefulWidgets anymore](#you-wont-need-statefulwidgets-anymore)  
93 - - [Why it exists](#why-it-exists)  
94 - - [Other ways of using it](#other-ways-of-using-it)  
95 - - [Unique IDs](#unique-ids)  
96 - - [Reactive State Manager](#reactive-state-manager)  
97 - - [Advantages](#advantages-1)  
98 - - [Usage](#usage-1)  
99 - - [Where .obs can be used](#where-obs-can-be-used)  
100 - - [Note about Lists](#note-about-lists)  
101 - - [Why i have to use .value?](#why-i-have-to-use-value)  
102 - - [Obx()](#obx)  
103 - - [Workers:](#workers)  
104 - - [Mixing the two state managers](#mixing-the-two-state-managers)  
105 - - [GetBuilder vs GetX && Obx vs MixinBuilder](#getbuilder-vs-getx-vs-obx-vs-mixinbuilder)  
106 -- [Dependency Management](#dependency-management)  
107 - - [Simple Instance Manager](#simple-instance-manager)  
108 - - [Bindings](#bindings)  
109 - - [How to use](#how-to-use-1)  
110 - - [SmartManagement](#smartmanagement)  
111 -- [Utils](#utils)  
112 - - [Change Theme](#change-theme)  
113 - - [Other Advanced APIs and Manual configurations](#other-advanced-apis-and-manual-configurations)  
114 - - [Optional Global Settings](#optional-global-settings)  
115 -- [Breaking changes from 2.0](#breaking-changes-from-2.0) 104 +### In-depth explanation
116 105
117 -*Want to contribute to the project? We will be proud to highlight you as one of our collaborators. Here are some points where you can contribute and make Get (and Flutter) even better.* 106 +**See an more in-depth explanation of state management [here](./docs/en_US/state_management.md). There you will see more examples and also the differente between the simple stage manager and the reactive state manager**
118 107
119 -- Helping to translate the readme into other languages.  
120 -- Adding documentation to the readme (not even half of Get's functions have been documented yet).  
121 -- Write articles or make videos teaching how to use Get (they will be inserted in the Readme and in the future in our Wiki).  
122 -- Offering PRs for code/tests.  
123 -- Including new functions. 108 +## Route management
124 109
125 -# Route Management  
126 -  
127 -Any contribution is welcome! 110 +See a more in-depth explanation of route management [here](./docs/en_US/route_management.md)
128 111
129 -## How to use? 112 +If you are going to use routes/snackbars/dialogs/bottomsheets without context, GetX is excellent for you too, just see it:
130 113
131 -Add this to your pubspec.yaml file:  
132 -  
133 -```  
134 -dependencies:  
135 - get:  
136 -```  
137 -If you are going to use routes/snackbars/dialogs/bottomsheets without context, or use the high-level Get APIs, you need to simply add "Get" before your MaterialApp, turning it into GetMaterialApp and enjoy! 114 +Add "Get" before your MaterialApp, turning it into GetMaterialApp
138 115
139 ```dart 116 ```dart
140 GetMaterialApp( // Before: MaterialApp( 117 GetMaterialApp( // Before: MaterialApp(
@@ -142,7 +119,6 @@ GetMaterialApp( // Before: MaterialApp( @@ -142,7 +119,6 @@ GetMaterialApp( // Before: MaterialApp(
142 ) 119 )
143 ``` 120 ```
144 121
145 -## Navigation without named routes  
146 To navigate to a new screen: 122 To navigate to a new screen:
147 123
148 ```dart 124 ```dart
@@ -168,985 +144,21 @@ Get.offAll(NextScreen()); @@ -168,985 +144,21 @@ Get.offAll(NextScreen());
168 ``` 144 ```
169 145
170 To navigate to the next route, and receive or update data as soon as you return from it: 146 To navigate to the next route, and receive or update data as soon as you return from it:
171 -```dart  
172 -var data = await Get.to(Payment());  
173 -```  
174 -on other screen, send a data for previous route:  
175 -  
176 -```dart  
177 -Get.back(result: 'success');  
178 -```  
179 -And use it:  
180 -  
181 -ex:  
182 -```dart  
183 -if(data == 'success') madeAnything();  
184 -```  
185 -  
186 -Don't you want to learn our syntax?  
187 -Just change the Navigator (uppercase) to navigator (lowercase), and you will have all the functions of the standard navigation, without having to use context  
188 -Example:  
189 147
190 ```dart 148 ```dart
191 -  
192 -// Default Flutter navigator  
193 -Navigator.of(context).push(  
194 - context,  
195 - MaterialPageRoute(  
196 - builder: (BuildContext context) {  
197 - return HomePage();  
198 - },  
199 - ),  
200 -);  
201 -  
202 -// Get using Flutter syntax without needing context  
203 -navigator.push(  
204 - MaterialPageRoute(  
205 - builder: (_) {  
206 - return HomePage();  
207 - },  
208 - ),  
209 -);  
210 -  
211 -// Get syntax (It is much better, but you have the right to disagree)  
212 -Get.to(HomePage());  
213 -  
214 -  
215 -```  
216 -  
217 -## Navigation with named routes  
218 -- If you prefer to navigate by namedRoutes, Get also supports this.  
219 -  
220 -To navigate to nextScreen  
221 -```dart  
222 -Get.toNamed("/NextScreen");  
223 -```  
224 -To navigate and remove the previous screen from the tree.  
225 -```dart  
226 -Get.offNamed("/NextScreen");  
227 -```  
228 -To navigate and remove all previous screens from the tree.  
229 -```dart  
230 -Get.offAllNamed("/NextScreen");  
231 -```  
232 -  
233 -To define routes, use GetMaterialApp:  
234 -  
235 -```dart  
236 -void main() {  
237 - runApp(  
238 - GetMaterialApp(  
239 - initialRoute: '/',  
240 - getPages: [  
241 - GetPage(name: '/', page: () => MyHomePage()),  
242 - GetPage(name: '/second', page: () => Second()),  
243 - GetPage(  
244 - name: '/third',  
245 - page: () => Third(),  
246 - transition: Transition.zoom  
247 - ),  
248 - ],  
249 - )  
250 - );  
251 -}  
252 -```  
253 -  
254 -### Send data to named Routes:  
255 -  
256 -Just send what you want for arguments. Get accepts anything here, whether it is a String, a Map, a List, or even a class instance.  
257 -```dart  
258 -Get.toNamed("/NextScreen", arguments: 'Get is the best');  
259 -```  
260 -on your class or controller:  
261 -  
262 -```dart  
263 -print(Get.arguments);  
264 -//print out: Get is the best  
265 -```  
266 -  
267 -### Dynamic urls links  
268 -Get offer advanced dynamic urls just like on the Web. Web developers have probably already wanted this feature on Flutter, and most likely have seen a package promise this feature and deliver a totally different syntax than a URL would have on web, but Get also solves that.  
269 -  
270 -```dart  
271 -Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo");  
272 -```  
273 -on your controller/bloc/stateful/stateless class:  
274 -  
275 -```dart  
276 -print(Get.parameters['id']);  
277 -// out: 354  
278 -print(Get.parameters['name']);  
279 -// out: Enzo  
280 -```  
281 -  
282 -You can also receive NamedParameters with Get easily:  
283 -  
284 -```dart  
285 -void main() {  
286 - runApp(  
287 - GetMaterialApp(  
288 - initialRoute: '/',  
289 - getPages: [  
290 - GetPage(  
291 - name: '/',  
292 - page: () => MyHomePage(),  
293 - ),  
294 - GetPage(  
295 - name: '/profile/',  
296 - page: () => MyProfile(),  
297 - ),  
298 - //You can define a different page for routes with arguments, and another without arguments, but for that you must use the slash '/' on the route that will not receive arguments as above.  
299 - GetPage(  
300 - name: '/profile/:user',  
301 - page: () => UserProfile(),  
302 - ),  
303 - GetPage(  
304 - name: '/third',  
305 - page: () => Third(),  
306 - transition: Transition.cupertino  
307 - ),  
308 - ],  
309 - )  
310 - );  
311 -}  
312 -```  
313 -Send data on route name  
314 -```dart  
315 -Get.toNamed("/second/34954");  
316 -```  
317 -  
318 -On second screen take the data by parameter  
319 -  
320 -```dart  
321 -print(Get.parameters['user']);  
322 -// out: 34954  
323 -```  
324 -  
325 -And now, all you need to do is use Get.toNamed() to navigate your named routes, without any context (you can call your routes directly from your BLoC or Controller class), and when your app is compiled to the web, your routes will appear in the url <3  
326 -  
327 -  
328 -### Middleware  
329 -If you want listen Get events to trigger actions, you can to use routingCallback to it  
330 -```dart  
331 -GetMaterialApp(  
332 - routingCallback: (routing) {  
333 - if(routing.current == '/second'){  
334 - openAds();  
335 - }  
336 - }  
337 -)  
338 -```  
339 -If you are not using GetMaterialApp, you can use the manual API to attach Middleware observer.  
340 -  
341 -```dart  
342 -void main() {  
343 - runApp(  
344 - MaterialApp(  
345 - onGenerateRoute: Router.generateRoute,  
346 - initialRoute: "/",  
347 - navigatorKey: Get.key,  
348 - navigatorObservers: [  
349 - GetObserver(MiddleWare.observer), // HERE !!!  
350 - ],  
351 - ),  
352 - );  
353 -}  
354 -```  
355 -Create a MiddleWare class  
356 -  
357 -```dart  
358 -class MiddleWare {  
359 - static observer(Routing routing) {  
360 - /// You can listen in addition to the routes, the snackbars, dialogs and bottomsheets on each screen.  
361 - ///If you need to enter any of these 3 events directly here,  
362 - ///you must specify that the event is != Than you are trying to do.  
363 - if (routing.current == '/second' && !routing.isSnackbar) {  
364 - Get.snackbar("Hi", "You are on second route");  
365 - } else if (routing.current =='/third'){  
366 - print('last route called');  
367 - }  
368 - }  
369 -}  
370 -```  
371 -  
372 -Now, use Get on your code:  
373 -  
374 -```dart  
375 -class First extends StatelessWidget {  
376 - @override  
377 - Widget build(BuildContext context) {  
378 - return Scaffold(  
379 - appBar: AppBar(  
380 - leading: IconButton(  
381 - icon: Icon(Icons.add),  
382 - onPressed: () {  
383 - Get.snackbar("hi", "i am a modern snackbar");  
384 - },  
385 - ),  
386 - title: Text('First Route'),  
387 - ),  
388 - body: Center(  
389 - child: RaisedButton(  
390 - child: Text('Open route'),  
391 - onPressed: () {  
392 - Get.toNamed("/second");  
393 - },  
394 - ),  
395 - ),  
396 - );  
397 - }  
398 -}  
399 -  
400 -class Second extends StatelessWidget {  
401 - @override  
402 - Widget build(BuildContext context) {  
403 - return Scaffold(  
404 - appBar: AppBar(  
405 - leading: IconButton(  
406 - icon: Icon(Icons.add),  
407 - onPressed: () {  
408 - Get.snackbar("hi", "i am a modern snackbar");  
409 - },  
410 - ),  
411 - title: Text('second Route'),  
412 - ),  
413 - body: Center(  
414 - child: RaisedButton(  
415 - child: Text('Open route'),  
416 - onPressed: () {  
417 - Get.toNamed("/third");  
418 - },  
419 - ),  
420 - ),  
421 - );  
422 - }  
423 -}  
424 -  
425 -class Third extends StatelessWidget {  
426 - @override  
427 - Widget build(BuildContext context) {  
428 - return Scaffold(  
429 - appBar: AppBar(  
430 - title: Text("Third Route"),  
431 - ),  
432 - body: Center(  
433 - child: RaisedButton(  
434 - onPressed: () {  
435 - Get.back();  
436 - },  
437 - child: Text('Go back!'),  
438 - ),  
439 - ),  
440 - );  
441 - }  
442 -}  
443 -```  
444 -## Navigation without context  
445 -  
446 -### SnackBars  
447 -  
448 -To have a simple SnackBar with Flutter, you must get the context of Scaffold, or you must use a GlobalKey attached to your Scaffold  
449 -  
450 -```dart  
451 -final snackBar = SnackBar(  
452 - content: Text('Hi!'),  
453 - action: SnackBarAction(  
454 - label: 'I am a old and ugly snackbar :(',  
455 - onPressed: (){}  
456 - ),  
457 -);  
458 -// Find the Scaffold in the widget tree and use  
459 -// it to show a SnackBar.  
460 -Scaffold.of(context).showSnackBar(snackBar);  
461 -```  
462 -  
463 -With Get:  
464 -  
465 -```dart  
466 -Get.snackbar('Hi', 'i am a modern snackbar');  
467 -```  
468 -  
469 -With Get, all you have to do is call your Get.snackbar from anywhere in your code or customize it however you want!  
470 -  
471 -```dart  
472 -Get.snackbar(  
473 - "Hey i'm a Get SnackBar!", // title  
474 - "It's unbelievable! I'm using SnackBar without context, without boilerplate, without Scaffold, it is something truly amazing!", // message  
475 - icon: Icon(Icons.alarm),  
476 - shouldIconPulse: true,  
477 - onTap:(){},  
478 - barBlur: 20,  
479 - isDismissible: true,  
480 - duration: Duration(seconds: 3),  
481 -);  
482 -  
483 -  
484 - ////////// ALL FEATURES //////////  
485 - // Color colorText,  
486 - // Duration duration,  
487 - // SnackPosition snackPosition,  
488 - // Widget titleText,  
489 - // Widget messageText,  
490 - // bool instantInit,  
491 - // Widget icon,  
492 - // bool shouldIconPulse,  
493 - // double maxWidth,  
494 - // EdgeInsets margin,  
495 - // EdgeInsets padding,  
496 - // double borderRadius,  
497 - // Color borderColor,  
498 - // double borderWidth,  
499 - // Color backgroundColor,  
500 - // Color leftBarIndicatorColor,  
501 - // List<BoxShadow> boxShadows,  
502 - // Gradient backgroundGradient,  
503 - // FlatButton mainButton,  
504 - // OnTap onTap,  
505 - // bool isDismissible,  
506 - // bool showProgressIndicator,  
507 - // AnimationController progressIndicatorController,  
508 - // Color progressIndicatorBackgroundColor,  
509 - // Animation<Color> progressIndicatorValueColor,  
510 - // SnackStyle snackStyle,  
511 - // Curve forwardAnimationCurve,  
512 - // Curve reverseAnimationCurve,  
513 - // Duration animationDuration,  
514 - // double barBlur,  
515 - // double overlayBlur,  
516 - // Color overlayColor,  
517 - // Form userInputForm  
518 - ///////////////////////////////////  
519 -```  
520 -If you prefer the traditional snackbar, or want to customize it from scratch, including adding just one line (Get.snackbar makes use of a mandatory title and message), you can use  
521 -`Get.rawSnackbar();` which provides the RAW API on which Get.snackbar was built.  
522 -  
523 -### Dialogs  
524 -  
525 -To open dialog:  
526 -  
527 -```dart  
528 -Get.dialog(YourDialogWidget());  
529 -```  
530 -  
531 -To open default dialog:  
532 -  
533 -```dart  
534 -Get.defaultDialog(  
535 - onConfirm: () => print("Ok"),  
536 - middleText: "Dialog made in 3 lines of code"  
537 -);  
538 -```  
539 -You can also use Get.generalDialog instead of showGeneralDialog.  
540 -  
541 -For all other Flutter dialog widgets, including cupertinos, you can use Get.overlayContext instead of context, and open it anywhere in your code.  
542 -For widgets that don't use Overlay, you can use Get.context.  
543 -These two contexts will work in 99% of cases to replace the context of your UI, except for cases where inheritedWidget is used without a navigation context.  
544 -  
545 -### BottomSheets  
546 -Get.bottomSheet is like showModalBottomSheet, but don't need of context.  
547 -  
548 -```dart  
549 -Get.bottomSheet(  
550 - Container(  
551 - child: Wrap(  
552 - children: <Widget>[  
553 - ListTile(  
554 - leading: Icon(Icons.music_note),  
555 - title: Text('Music'),  
556 - onTap: () => {}  
557 - ),  
558 - ListTile(  
559 - leading: Icon(Icons.videocam),  
560 - title: Text('Video'),  
561 - onTap: () => {},  
562 - ),  
563 - ],  
564 - ),  
565 - );  
566 -);  
567 -```  
568 -  
569 -  
570 -## Nested Navigation  
571 -  
572 -Get made Flutter's nested navigation even easier.  
573 -You don't need the context, and you will find your navigation stack by Id.  
574 -  
575 -- NOTE: Creating parallel navigation stacks can be dangerous. The ideal is not to use NestedNavigators, or to use sparingly. If your project requires it, go ahead, but keep in mind that keeping multiple navigation stacks in memory may not be a good idea for RAM consumption.  
576 -  
577 -See how simple it is:  
578 -```dart  
579 -Navigator(  
580 - key: Get.nestedKey(1), // create a key by index  
581 - initialRoute: '/',  
582 - onGenerateRoute: (settings) {  
583 - if (settings.name == '/') {  
584 - return GetPageRoute(  
585 - page: Scaffold(  
586 - appBar: AppBar(  
587 - title: Text("Main"),  
588 - ),  
589 - body: Center(  
590 - child: FlatButton(  
591 - color: Colors.blue,  
592 - onPressed: () {  
593 - Get.toNamed('/second', id:1); // navigate by your nested route by index  
594 - },  
595 - child: Text("Go to second"),  
596 - ),  
597 - ),  
598 - ),  
599 - );  
600 - } else if (settings.name == '/second') {  
601 - return GetPageRoute(  
602 - page: Center(  
603 - child: Scaffold(  
604 - appBar: AppBar(  
605 - title: Text("Main"),  
606 - ),  
607 - body: Center(  
608 - child: Text("second")  
609 - ),  
610 - ),  
611 - ),  
612 - );  
613 - }  
614 - }  
615 -),  
616 -```  
617 -  
618 -  
619 -# State Management  
620 -  
621 -There are currently several state managers for Flutter. However, most of them involve using ChangeNotifier to update widgets and this is a bad and very bad approach to performance of medium or large applications. You can check in the official Flutter documentation that [ChangeNotifier should be used with 1 or a maximum of 2 listeners](https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html), making it practically unusable for any application medium or large.  
622 -  
623 -Other state managers are good, but have their nuances:  
624 -- BLoC is very safe and efficient, but it is very complex for beginners, which has kept people from developing with Flutter.  
625 -- MobX is easier than BLoC and reactive, almost perfect, I would say, but you need to use a code generator, that for large applications, reduces productivity, since you will need to drink a lot of coffees until your code is ready again after a `flutter clean` (And this is not MobX's fault, but the codegen which is really slow!).  
626 -- Provider uses InheritedWidget to deliver the same listener, as a way of solving the problem reported above with ChangeNotifier, which implies that any access to its ChangeNotifier class must be within the widget tree because of the context to access o Inherited.  
627 -  
628 -  
629 -Get isn't better or worse than any other state manager, but that you should analyze these points as well as the points below to choose between using Get in pure form (Vanilla), or using it in conjunction with another state manager. Definitely, Get is not the enemy of any other state manager, because Get is a microframework, not just a state manager, and can be used either alone or in conjunction with them.  
630 -  
631 -## Simple State Manager  
632 -  
633 -Get has a state manager that is extremely light and easy, which does not use ChangeNotifier, will meet the need especially for those new to Flutter, and will not cause problems for large applications.  
634 -  
635 -### Advantages  
636 -  
637 -1. Update only the required widgets.  
638 -  
639 -2. Does not use changeNotifier, it is the state manager that uses less memory (close to 0mb).  
640 -  
641 -3. Forget StatefulWidget! With Get you will never need it. With the other state managers, you will probably have to use a StatefulWidget to get the instance of your Provider, BLoC, MobX Controller, etc. But have you ever stopped to think that your appBar, your scaffold, and most of the widgets that are in your class are stateless? So why save the state of an entire class, if you can only save the state of the Widget that is stateful? Get solves that, too. Create a Stateless class, make everything stateless. If you need to update a single component, wrap it with GetBuilder, and its state will be maintained.  
642 -  
643 -4. Organize your project for real! Controllers must not be in your UI, place your TextEditController, or any controller you use within your Controller class.  
644 -  
645 -5. Do you need to trigger an event to update a widget as soon as it is rendered? GetBuilder has the property "initState", just like StatefulWidget, and you can call events from your controller, directly from it, no more events being placed in your initState.  
646 -  
647 -6. Do you need to trigger an action like closing streams, timers and etc? GetBuilder also has the dispose property, where you can call events as soon as that widget is destroyed.  
648 -  
649 -7. Use streams only if necessary. You can use your StreamControllers inside your controller normally, and use StreamBuilder also normally, but remember, a stream reasonably consumes memory, reactive programming is beautiful, but you shouldn't abuse it. 30 streams open simultaneously can be worse than changeNotifier (and changeNotifier is very bad).  
650 -  
651 -8. Update widgets without spending ram for that. Get stores only the GetBuilder creator ID, and updates that GetBuilder when necessary. The memory consumption of the get ID storage in memory is very low even for thousands of GetBuilders. When you create a new GetBuilder, you are actually sharing the state of GetBuilder that has a creator ID. A new state is not created for each GetBuilder, which saves A LOT OF ram for large applications. Basically your application will be entirely Stateless, and the few Widgets that will be Stateful (within GetBuilder) will have a single state, and therefore updating one will update them all. The state is just one.  
652 -  
653 -9. Get is omniscient and in most cases it knows exactly the time to take a controller out of memory. You should not worry about when to dispose of a controller, Get knows the best time to do this.  
654 -  
655 -### Usage  
656 -  
657 -```dart  
658 -// Create controller class and extends GetxController  
659 -class Controller extends GetxController {  
660 - int counter = 0;  
661 - void increment() {  
662 - counter++;  
663 - update(); // use update() to update counter variable on UI when increment be called  
664 - }  
665 -}  
666 -// On your Stateless/Stateful class, use GetBuilder to update Text when increment be called  
667 -GetBuilder<Controller>(  
668 - init: Controller(), // INIT IT ONLY THE FIRST TIME  
669 - builder: (_) => Text(  
670 - '${_.counter}',  
671 - ),  
672 -)  
673 -//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.  
674 -```  
675 -**Done!**  
676 -- You have already learned how to manage states with Get.  
677 -  
678 -- Note: You may want a larger organization, and not use the init property. For that, you can create a class and extends Bindings class, and within it mention the controllers that will be created within that route. Controllers will not be created at that time, on the contrary, this is just a statement, so that the first time you use a Controller, Get will know where to look. Get will remain lazyLoad, and will continue to dispose Controllers when they are no longer needed. See the pub.dev example to see how it works.  
679 -  
680 -  
681 -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):  
682 -  
683 -```dart  
684 -class OtherClass extends StatelessWidget {  
685 - @override  
686 - Widget build(BuildContext context) {  
687 - return Scaffold(  
688 - body: Center(  
689 - child: GetBuilder<Controller>(  
690 - builder: (s) => Text('${s.counter}'),  
691 - ),  
692 - ),  
693 - );  
694 - }  
695 -  
696 -```  
697 -If you need to use your controller in many other places, and outside of GetBuilder, just create a get in your controller and have it easily. (or use `Get.find<Controller>()`)  
698 -  
699 -```dart  
700 -class Controller extends GetxController {  
701 -  
702 - /// You do not need that. I recommend using it just for ease of syntax.  
703 - /// with static method: Controller.to.counter();  
704 - /// with no static method: Get.find<Controller>().counter();  
705 - /// There is no difference in performance, nor any side effect of using either syntax. Only one does not need the type, and the other the IDE will autocomplete it.  
706 - static Controller get to => Get.find(); // add this line  
707 -  
708 - int counter = 0;  
709 - void increment() {  
710 - counter++;  
711 - update();  
712 - }  
713 -}  
714 -```  
715 -And then you can access your controller directly, that way:  
716 -```dart  
717 -FloatingActionButton(  
718 - onPressed: () {  
719 - Controller.to.increment(),  
720 - } // This is incredibly simple!  
721 - child: Text("${Controller.to.counter}"),  
722 -),  
723 -```  
724 -When you press FloatingActionButton, all widgets that are listening to the 'counter' variable will be updated automatically.  
725 -  
726 -### How it handles controllers  
727 -Let's say we have this:  
728 -  
729 -`Class a => Class B (has controller X) => Class C (has controller X)`  
730 -  
731 -In class A the controller is not yet in memory, because you have not used it yet (Get is lazyLoad). In class B you used the controller, and it entered memory. In class C you used the same controller as in class B, Get will share the state of controller B with controller C, and the same controller is still in memory. If you close screen C and screen B, Get will automatically take controller X out of memory and free up resources, because Class a is not using the controller. If you navigate to B again, controller X will enter memory again, if instead of going to class C, you return to class A again, Get will take the controller out of memory in the same way. If class C didn't use the controller, and you took class B out of memory, no class would be using controller X and likewise it would be disposed of. The only exception that can mess with Get, is if you remove B from the route unexpectedly, and try to use the controller in C. In this case, the creator ID of the controller that was in B was deleted, and Get was programmed to remove it from memory every controller that has no creator ID. If you intend to do this, add the "autoRemove: false" flag to class B's GetBuilder and use adoptID = true; in class C's GetBuilder.  
732 -  
733 -### You won't need StatefulWidgets anymore  
734 -Using StatefulWidgets means storing the state of entire screens unnecessarily, even because if you need to minimally rebuild a widget, you will embed it in a Consumer/Observer/BlocProvider/GetBuilder/GetX/Obx, which will be another StatefulWidget.  
735 -The StatefulWidget class is a class larger than StatelessWidget, which will allocate more RAM, and this may not make a significant difference between one or two classes, but it will most certainly do when you have 100 of them!  
736 -Unless you need to use a mixin, like TickerProviderStateMixin, it will be totally unnecessary to use a StatefulWidget with Get.  
737 -  
738 -You can call all methods of a StatefulWidget directly from a GetBuilder.  
739 -If you need to call initState() or dispose() method for example, you can call them directly;  
740 -  
741 -```dart  
742 -GetBuilder<Controller>(  
743 - initState: (_) => Controller.to.fetchApi(),  
744 - dispose: (_) => Controller.to.closeStreams(),  
745 - builder: (s) => Text('${s.username}'),  
746 -),  
747 -```  
748 -  
749 -A much better approach than this is to use the onInit() and onClose() method directly from your controller.  
750 -  
751 -```dart  
752 -@override  
753 -void onInit() {  
754 - fetchApi();  
755 - super.onInit();  
756 -}  
757 -```  
758 -  
759 -- NOTE: If you want to start a method at the moment the controller is called for the first time, you DON'T NEED to use constructors for this, in fact, using a performance-oriented package like Get, this borders on bad practice, because it deviates from the logic in which the controllers are created or allocated (if you create an instance of this controller, the constructor will be called immediately, you will be populating a controller before it is even used, you are allocating memory without it being in use, this definitely hurts the principles of this library). The onInit() methods; and onClose(); were created for this, they will be called when the Controller is created, or used for the first time, depending on whether you are using Get.lazyPut or not. If you want, for example, to make a call to your API to populate data, you can forget about the old-fashioned method of initState/dispose, just start your call to the api in onInit, and if you need to execute any command like closing streams, use the onClose() for that.  
760 -  
761 -### Why it exists  
762 -The purpose of this package is precisely to give you a complete solution for navigation of routes, management of dependencies and states, using the least possible dependencies, with a high degree of decoupling. Get engages all high and low level Flutter APIs within itself, to ensure that you work with the least possible coupling. We centralize everything in a single package, to ensure that you don't have any kind of coupling in your project. That way, you can put only widgets in your view, and leave the part of your team that works with the business logic free, to work with the business logic without depending on any element of the View. This provides a much cleaner working environment, so that part of your team works only with widgets, without worrying about sending data to your controller, and part of your team works only with the business logic in its breadth, without depending on no element of the view.  
763 -  
764 -So to simplify this:  
765 -You don't need to call methods in initState and send them by parameter to your controller, nor use your controller constructor for that, you have the onInit() method that is called at the right time for you to start your services.  
766 -You do not need to call the device, you have the onClose() method that will be called at the exact moment when your controller is no longer needed and will be removed from memory. That way, leave views for widgets only, refrain from any kind of business logic from it.  
767 -  
768 -Do not call a dispose method inside GetxController, it will not do anything, remember that the controller is not a Widget, you should not "dispose" it, and it will be automatically and intelligently removed from memory by Get. If you used any stream on it and want to close it, just insert it into the close method. Example:  
769 -  
770 -```dart  
771 -class Controller extends GetxController {  
772 - StreamController<User> user = StreamController<User>();  
773 - StreamController<String> name = StreamController<String>();  
774 -  
775 - /// close stream = onClose method, not dispose.  
776 - @override  
777 - void onClose() {  
778 - user.close();  
779 - name.close();  
780 - super.onClose();  
781 - }  
782 -}  
783 -```  
784 -Controller life cycle:  
785 -- onInit() where it is created.  
786 -- onClose() where it is closed to make any changes in preparation for the delete method  
787 -- deleted: you do not have access to this API because it is literally removing the controller from memory. It is literally deleted, without leaving any trace.  
788 -  
789 -### Other ways of using it  
790 -  
791 -You can use Controller instance directly on GetBuilder value:  
792 -  
793 -```dart  
794 -GetBuilder<Controller>(  
795 - init: Controller(),  
796 - builder: (value) => Text(  
797 - '${value.counter}', //here  
798 - ),  
799 -),  
800 -```  
801 -You may also need an instance of your controller outside of your GetBuilder, and you can use these approaches to achieve this:  
802 -  
803 -```dart  
804 -class Controller extends GetxController {  
805 - static Controller get to => Get.find();  
806 -[...]  
807 -}  
808 -// on you view:  
809 -GetBuilder<Controller>(  
810 - init: Controller(), // use it only first time on each controller  
811 - builder: (_) => Text(  
812 - '${Controller.to.counter}', //here  
813 - )  
814 -),  
815 -```  
816 -or  
817 -```dart  
818 -class Controller extends GetxController {  
819 - // static Controller get to => Get.find(); // with no static get  
820 -[...]  
821 -}  
822 -// on stateful/stateless class  
823 -GetBuilder<Controller>(  
824 - init: Controller(), // use it only first time on each controller  
825 - builder: (_) => Text(  
826 - '${Get.find<Controller>().counter}', //here  
827 - ),  
828 -),  
829 -```  
830 -  
831 -- 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:  
832 -  
833 -```dart  
834 -Controller controller = Controller();  
835 -[...]  
836 -GetBuilder<Controller>(  
837 - init: controller, //here  
838 - builder: (_) => Text(  
839 - '${controller.counter}', // here  
840 - ),  
841 -),  
842 -  
843 -```  
844 -  
845 -### Unique IDs  
846 -If you want to refine a widget's update control with GetBuilder, you can assign them unique IDs:  
847 -```dart  
848 -GetBuilder<Controller>(  
849 - id: 'text'  
850 - init: Controller(), // use it only first time on each controller  
851 - builder: (_) => Text(  
852 - '${Get.find<Controller>().counter}', //here  
853 - ),  
854 -),  
855 -```  
856 -And update it this form:  
857 -```dart  
858 -update(['text']);  
859 -```  
860 -You can also impose conditions for the update:  
861 -  
862 -```dart  
863 -update(['text'], counter < 10);  
864 -```  
865 -  
866 -GetX does this automatically and only reconstructs the widget that uses the exact variable that was changed, if you change a variable to the same as the previous one and that does not imply a change of state , GetX will not rebuild the widget to save memory and CPU cycles (3 is being displayed on the screen, and you change the variable to 3 again. In most state managers, this will cause a new rebuild, but with GetX the widget will only is rebuilt again, if in fact his state has changed).  
867 -  
868 -## Reactive State Manager  
869 -  
870 -Reactive programming can alienate many people because it is said to be complicated. Getx turns reactive programming into something so simple, that it can be used and learned by those who started at that very moment in Flutter. No, you will not need to create StreamControllers. You also won't need to create a StreamBuilder for each variable. You will not need to create a class for each state. You will not need to create a get for an initial value. Reactive programming with Get is as easy as using setState (or even easier!).  
871 -  
872 -Let's imagine that you have a name variable and want that every time you change it, all widgets that use it are automatically changed.  
873 -  
874 -This is your count variable:  
875 -```dart  
876 -var name = 'Jonatas Borges';  
877 -```  
878 -To make it observable, you just need to add ".obs" to the end of it:  
879 -```dart  
880 -var name = 'Jonatas Borges'.obs;  
881 -```  
882 -  
883 -This borders on absurdity when it comes to practicality. What did we do under the hood? We created a stream of Strings, assigned the initial value "Jonatas Borges", we warn all widgets that use "Jonatas Borges" that they now belong to this variable, and when it is changed, they will be changed too. This is the magic of Get, that only dart allows us to do this.  
884 -  
885 -Okay, but as we know, a widget can only be changed if it is inside a function, because static classes do not have the power to "auto-change". You will need to create a StreamBuilder, subscribe to listen to this variable, and create a "cascade" of StreamBuilder if you want to change several variables in the same scope, right?  
886 -No, you don't need a StreamBuilder, but you are right about static classes.  
887 -  
888 -Well, in the view we usually have a lot of boilerplate when we want to change a specific widget. With Get you can also forget about this Boilerplate. StreamBuilder? initialValue? builder?  
889 -No, you just need to play this variable inside an Obx widget.  
890 -```dart  
891 -Obx (() => Text (controller.name));  
892 -```  
893 -  
894 -What do you need to memorize? "Obx(() =>" You are just passing that widget through an arrow-function into an Obx. Obx is smart, and will only be changed if the value of name is changed. If name is "John" and you change it to "John", it will not have any changes on the screen, and Obx will simply ignore this change, and will not rebuild the widget, to save resources. Isn't that amazing?  
895 -  
896 -What if I have 5 observable variables within an Obx? It will update when any of them are changed. And if I have 30 variables in a class, when I update one, will it update all variables that are in that class? No, just the specific widget that uses that variable. And if I machine-gun my observable variable 1 billion times with the same value, will I have freeze on the screen for unnecessary reconstructions? No, GetX only updates the screen when the variable changes on the screen, if the screen remains the same, it will not reconstruct anything.  
897 -  
898 -### Advantages  
899 -GetBuilder is aimed precisely at multiple state control. Imagine that you added 30 products to a cart, you click delete one, at the same time that the list is updated, the price is updated and the badge in the shopping cart is updated to a smaller number. This type of approach makes GetBuilder killer, because it groups states and changes them all at once without any "computational logic" for that. GetBuilder was created with this type of situation in mind, since for ephemeral change of state, you can use setState and you would not need a state manager for this. However, there are situations where you want only the widget where a certain variable has been changed to be rebuilt, and this is what GetX does with a mastery never seen before.  
900 -  
901 -That way, if you want an individual controller, you can assign IDs for that, or use GetX. This is up to you, remembering that the more "individual" widgets you have, the more the performance of GetX will stand out, while the performance of GetBuilder should be superior, when there is multiple change of state.  
902 -  
903 -You can use both in any situation, but if you want to tune their application to the maximum possible performance, I would say that: if your variables are changed at different times, use GetX, because there is no competition for it when the subject is to rebuild only what is necessary, if you do not need unique IDs, because all your variables will be changed when you perform an action, use GetBuilder, because it is a simple state updater in blocks, made in a few lines of code, to make just what he promises to do: update state in blocks. There is no way to compare RAM, CPU, or anything else from a giant state manager to a simple StatefulWidget (like GetBuilder) that is updated when you call update(). It was done in a simple way, to have the least computational logic involved, just to fulfill a single purpose and spend the minimum resources possible for that purpose.  
904 -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 .  
905 -  
906 -If you want power, Get gives you the most advanced state manager you could ever have.  
907 -GetX was built 100% based on Streams, and give you all the firepower that BLoC gave you, with an easier facility than using MobX.  
908 -Without decorations, you can turn anything into Observable with just a ".obs".  
909 -  
910 -Maximum performance: In addition to having a smart algorithm for minimal reconstruction, Get uses comparators to make sure the state has changed. If you experience any errors in your application, and send a duplicate change of state, Get will ensure that your application does not collapse.  
911 -The state only changes if the values ​​change. That's the main difference between Get, and using Computed from MobX. When joining two observables, when one is changed, the hearing of that observable will change. With Get, if you join two variables (which is unnecessary computed for that), GetX (similar to Observer) will only change if it implies a real change of state.  
912 -  
913 -### Usage  
914 -  
915 -You have 3 ways to turn a variable into an observable.  
916 -The first is using Rx{Type}.  
917 -  
918 -```dart  
919 -var count = RxString();  
920 -```  
921 -The second is to use Rx and type it with `Rx<Type>`  
922 -```dart  
923 -var count = Rx<String>();  
924 -```  
925 -  
926 -The third, more practical, easy, and incredible approach, is just to add an .obs to your variable.  
927 -  
928 -```dart  
929 -var count = 0.obs;  
930 -  
931 -// or Rxint count = 0.obs;  
932 -// or Rx<int> count = 0.obs;  
933 -```  
934 -  
935 - As we know, Dart is now heading towards null safety. With that it is a good idea, from now on, you start to use your variables always with an initial value. Transforming a variable into an observable with an initial value with Get is the simplest and most practical approach that currently exists in Flutter. You will literally add a ".obs" to the end of your variable, and that’s it, you’ve made it observable, and its value will be the initial value, this is fantastic!  
936 -  
937 -You can add variables, and if you want to type your widget to get your controller inside, you just need to use GetX widget instead of Obx  
938 -```dart  
939 -final count1 = 0.obs;  
940 -final count2 = 0.obs;  
941 -int get sum => count1.value + count2.value;  
942 -```  
943 -  
944 -```dart  
945 -GetX<Controller>(  
946 - builder: (value) {  
947 - print("count 1 rebuild");  
948 - return Text('${value.count1.value}');  
949 - },  
950 -),  
951 -GetX<Controller>(  
952 - builder: (_) {  
953 - print("count 2 rebuild");  
954 - return Text('${_.count2.value}');  
955 - },  
956 -),  
957 -GetX<Controller>(  
958 - builder: (_) {  
959 - print("count 3 rebuild");  
960 - return Text('${_.sum}');  
961 - },  
962 -),  
963 -```  
964 -  
965 -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.  
966 -  
967 -If we change count 2, only count2 and 3 are reconstructed, because the value of 2 has changed, and the result of the sum is now 2.  
968 -  
969 -If we add the number 1 to count 1, which already contains 1, no widget is reconstructed. If we add a value of 1 for count 1 and a value of 2 for count 2, only 2 and 3 will be reconstructed, simply because GetX not only changes what is necessary, it avoids duplicating events.  
970 -  
971 -- NOTE: By default, the first event will allow rebuild even if it is the same. We created this behavior due to dualistic variables, such as Boolean.  
972 -Imagine you did this:  
973 -  
974 -```dart  
975 -var isLogged = false.obs;  
976 -```  
977 -  
978 -and then you check if a user is logged in to trigger an event in "ever".  
979 -  
980 -```dart  
981 -onInit(){  
982 - ever(isLogged, fireRoute);  
983 - isLogged.value = await Preferences.hasToken();  
984 -}  
985 -  
986 -fireRoute(logged) {  
987 - if (logged) {  
988 - Get.off(Home());  
989 - } else {  
990 - Get.off(Login());  
991 - }  
992 -}  
993 -```  
994 -  
995 -if hasToken was false, there would be no change to isLogged, so ever would never be called. To avoid this type of behavior, the first change to an observable will always trigger an event, even if it is the same.  
996 -You can remove this behavior if you want, using:  
997 -`isLogged.firstRebuild = false;`  
998 -  
999 -In addition, Get provides refined state control. You can condition an event (such as adding an object to a list), on a certain condition.  
1000 -  
1001 -```dart  
1002 -list.addIf(item<limit, item);  
1003 -```  
1004 -  
1005 -Without decorations, without a code generator, without complications, GetX will change the way you manage your states in Flutter, and that is not a promise, it is a certainty!  
1006 -  
1007 -Do you know Flutter's counter app? Your Controller class might look like this:  
1008 -  
1009 -```dart  
1010 -class CountCtl extends GetxController {  
1011 - final count = 0.obs;  
1012 -}  
1013 -```  
1014 -With a simple:  
1015 -```dart  
1016 -ctl.count.value++  
1017 -```  
1018 -  
1019 -You could update the counter variable in your UI, regardless of where it is stored.  
1020 -  
1021 -### Where .obs can be used  
1022 -You can transform anything on obs:  
1023 -  
1024 -```dart  
1025 -class RxUser {  
1026 - final name = "Camila".obs;  
1027 - final age = 18.obs;  
1028 -}  
1029 -  
1030 -class User {  
1031 - User({String name, int age});  
1032 - final rx = RxUser();  
1033 -  
1034 - String get name => rx.name.value;  
1035 - set name(String value) => rx.name.value = value;  
1036 -  
1037 - int get age => rx.age.value;  
1038 - set age(int value) => rx.age.value = value;  
1039 -}  
1040 -```  
1041 -  
1042 -```dart  
1043 -  
1044 -void main() {  
1045 - final user = User();  
1046 - print(user.name);  
1047 - user.age = 23;  
1048 - user.rx.age.listen((int age) => print(age));  
1049 - user.age = 24;  
1050 - user.age = 25;  
1051 -}  
1052 -___________  
1053 -out:  
1054 -Camila  
1055 -23  
1056 -24  
1057 -25  
1058 -  
1059 -```  
1060 -  
1061 -  
1062 -### Note about Lists  
1063 -Working with Lists using Get is the best and most enjoyable thing in the world. They are completely observable as are the objects within it. That way, if you add a value to a list, it will automatically rebuild the widgets that use it.  
1064 -You also don't need to use ".value" with lists, the amazing dart api allowed us to remove that, unfortunate primitive types like String and int cannot be extended, making the use of .value mandatory, but that won't be a problem if you work with gets and setters for these.  
1065 -  
1066 -```dart  
1067 -final list = List<User>().obs;  
1068 -```  
1069 -  
1070 -```dart  
1071 -ListView.builder (  
1072 - itemCount: list.lenght  
1073 -)  
1074 -```  
1075 -  
1076 -You don't have to work with sets if you don't want to. you can use the "assign 'and" assignAll "api.  
1077 -The "assign" api will clear your list, and add a single object that you want to start there.  
1078 -The "assignAll" api will clear the existing list and add any iterable objects that you inject into it.  
1079 -  
1080 -### Why i have to use .value?  
1081 -We could remove the obligation to use 'value' to String and int with a simple decoration and code generator, but the purpose of this lib is precisely not to need any external dependency. It is to offer an environment ready for programming, involving the essentials (management of routes, dependencies and states), in a simple, light and performance way without needing any external package. You can literally add 3 letters to your pubspec (get) and start programming. All solutions included by default, from route management to state management, aim at ease, productivity and performance. The total weight of this library is less than that of a single state manager, even though it is a complete solution, and that is what you must understand. If you are bothered by value, and like a code generator, MobX is a great alternative, and you can use it in conjunction with Get. For those who want to add a single dependency in pubspec and start programming without worrying about the version of a package being incompatible with another, or if the error of a state update is coming from the state manager or dependency, or still, do not want to worrying about the availability of controllers, whether literally "just programming", get is just perfect.  
1082 -  
1083 -If you have no problem with the MobX code generator, or have no problem with the BLoC boilerplate, you can simply use Get for routes, and forget that it has state manager. Get SEM and RSM were born out of necessity, my company had a project with more than 90 controllers, and the code generator simply took more than 30 minutes to complete its tasks after a Flutter Clean on a reasonably good machine, if your project it has 5, 10, 15 controllers, any state manager will supply you well. If you have an absurdly large project, and code generator is a problem for you, you have been awarded this solution.  
1084 -  
1085 -Obviously, if someone wants to contribute to the project and create a code generator, or something similar, I will link in this readme as an alternative, my need is not the need for all devs, but for now I say, there are good solutions that already do that, like MobX.  
1086 -  
1087 -### Obx()  
1088 -  
1089 -Typing in Get using Bindings is unnecessary. you can use the Obx widget instead of GetX which only receives the anonymous function that creates a widget.  
1090 -Obviously, if you don't use a type, you will need to have an instance of your controller to use the variables, or use `Get.find<Controller>()` .value or Controller.to.value to retrieve the value.  
1091 -  
1092 -### Workers:  
1093 -Workers will assist you, triggering specific callbacks when an event occurs.  
1094 -  
1095 -  
1096 -```dart  
1097 -/// Called every time the variable $_ is changed  
1098 -ever(count1, (_) => print("$_ has been changed"));  
1099 -  
1100 -/// Called only first time the variable $_ is changed  
1101 -once(count1, (_) => print("$_ was changed once"));  
1102 -  
1103 -/// Anti DDos - Called every time the user stops typing for 1 second, for example.  
1104 -debounce(count1, (_) => print("debouce$_"), time: Duration(seconds: 1));  
1105 -  
1106 -/// Ignore all changes within 1 second.  
1107 -interval(count1, (_) => print("interval $_"), time: Duration(seconds: 1)); 149 +var data = await Get.to(Payment());
1108 ``` 150 ```
1109 -- ever  
1110 -'ever' is called every time its variable is changed. That's it.  
1111 -  
1112 -- ever  
1113 -'once' is called only the first time the variable has been changed.  
1114 -  
1115 -- debounce  
1116 -'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.  
1117 -  
1118 -- interval  
1119 -'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.  
1120 -  
1121 -  
1122 -## Mixing the two state managers  
1123 -Some people opened a feature request, as they wanted to use only one type of reactive variable, and the other mechanics, and needed to insert an Obx into a GetBuilder for this. Thinking about it MixinBuilder was created. It allows both reactive changes by changing ".obs" variables, and mechanical updates via update(). However, of the 4 widgets he is the one that consumes the most resources, since in addition to having a Subscription to receive change events from his children, he subscribes to the update method of his controller.  
1124 -  
1125 -Extending GetxController is important, as they have life cycles, and can "start" and "end" events in their onInit() and onClose() methods. You can use any class for this, but I strongly recommend you use the GetxController class to place your variables, whether they are observable or not.  
1126 -  
1127 -## GetBuilder vs GetX vs Obx vs MixinBuilder  
1128 -In a decade working with programming I was able to learn some valuable lessons.  
1129 -  
1130 -My first contact with reactive programming was so "wow, this is incredible" and in fact reactive programming is incredible.  
1131 -However, it is not suitable for all situations. Often all you need is to change the state of 2 or 3 widgets at the same time, or an ephemeral change of state, in which case reactive programming is not bad, but it is not appropriate.  
1132 -  
1133 -Reactive programming has a higher consumption of RAM consumption that can be compensated for by the individual workflow, which will ensure that only one widget is rebuilt and when necessary, but creating a list with 80 objects, each with several streams is not a good one idea. Open the dart inspect and check how much a StreamBuilder consumes, and you'll understand what I'm trying to tell you.  
1134 -  
1135 -With that in mind, I created the simple state manager. It is simple, and that is exactly what you should demand from it: updating state in blocks in a simple way, and in the most economical way.  
1136 151
1137 -GetBuilder is very economical in RAM, and there is hardly a more economical approach than him (at least I can't imagine one, if it exists, please let us know). 152 +Noticed that you didn't had to use context to do any of these things? That's one of the biggest advantages of using Get route management. With this, you can execute all these methods from within your controller class, without worries.
1138 153
1139 -However, GetBuilder is still a mechanical state manager, you need to call update() just like you would need to call Provider's notifyListeners(). 154 +### In-Depth Explanation
1140 155
1141 -There are other situations where reactive programming is really interesting, and not working with it is the same as reinventing the wheel. With that in mind, GetX was created to provide everything that is most modern and advanced in a state manager. It updates only what is necessary and when necessary, if you have an error and send 300 state changes simultaneously, GetX will filter and update the screen only if the state actually changes. 156 +**Note: Get work with named routes too! As said in the beggining, there is a in-depth documentation [here](./docs/en_US/route_management.md)**
1142 157
1143 -GetX is still more economical than any other reactive state manager, but it consumes a little more RAM than GetBuilder. Thinking about it and aiming to maximize the consumption of resources that Obx was created. Unlike GetX and GetBuilder, you will not be able to initialize a controller inside an Obx, it is just a Widget with a StreamSubscription that receives change events from your children, that's all. It is more economical than GetX, but loses to GetBuilder, which was to be expected, since it is reactive, and GetBuilder has the most simplistic approach that exists, of storing a widget's hashcode and its StateSetter. With Obx you don't need to write your controller type, and you can hear the change from multiple different controllers, but it needs to be initialized before, either using the example approach at the beginning of this readme, or using the Bindings class. 158 +## Dependency management
1144 159
  160 +See a more in-depth explanation of dependency management [here](./docs/en_US/dependency_management.md)
1145 161
1146 -# Dependency Management  
1147 -  
1148 -  
1149 -## Simple Instance Manager  
1150 - Note: If you are using Get's State Manager, you don't have to worry about that, just read for information, but pay more attention to the bindings api, which will do all of this automatically for you. 162 - Note: If you are using Get's State Manager, you don't have to worry about that, just read for information, but pay more attention to the bindings api, which will do all of this automatically for you.
1151 163
1152 Are you already using Get and want to make your project as lean as possible? Get has a simple and powerful dependency manager that allows you to retrieve the same class as your Bloc or Controller with just 1 lines of code, no Provider context, no inheritedWidget: 164 Are you already using Get and want to make your project as lean as possible? Get has a simple and powerful dependency manager that allows you to retrieve the same class as your Bloc or Controller with just 1 lines of code, no Provider context, no inheritedWidget:
@@ -1154,6 +166,7 @@ Are you already using Get and want to make your project as lean as possible? Get @@ -1154,6 +166,7 @@ Are you already using Get and want to make your project as lean as possible? Get
1154 ```dart 166 ```dart
1155 Controller controller = Get.put(Controller()); // Rather Controller controller = Controller(); 167 Controller controller = Get.put(Controller()); // Rather Controller controller = Controller();
1156 ``` 168 ```
  169 +
1157 Instead of instantiating your class within the class you are using, you are instantiating it within the Get instance, which will make it available throughout your App. 170 Instead of instantiating your class within the class you are using, you are instantiating it within the Get instance, which will make it available throughout your App.
1158 So you can use your controller (or class Bloc) normally 171 So you can use your controller (or class Bloc) normally
1159 172
@@ -1167,6 +180,7 @@ Imagine that you have navigated through numerous routes, and you need a data tha @@ -1167,6 +180,7 @@ Imagine that you have navigated through numerous routes, and you need a data tha
1167 Controller controller = Get.find(); 180 Controller controller = Get.find();
1168 //Yes, it looks like Magic, Get will find your controller, and will deliver it to you. You can have 1 million controllers instantiated, Get will always give you the right controller. 181 //Yes, it looks like Magic, Get will find your controller, and will deliver it to you. You can have 1 million controllers instantiated, Get will always give you the right controller.
1169 ``` 182 ```
  183 +
1170 And then you will be able to recover your controller data that was obtained back there: 184 And then you will be able to recover your controller data that was obtained back there:
1171 185
1172 ```dart 186 ```dart
@@ -1174,107 +188,36 @@ Text(controller.textFromApi); @@ -1174,107 +188,36 @@ Text(controller.textFromApi);
1174 ``` 188 ```
1175 189
1176 Looking for lazy loading? You can declare all your controllers, and it will be called only when someone needs it. You can do this with: 190 Looking for lazy loading? You can declare all your controllers, and it will be called only when someone needs it. You can do this with:
  191 +
1177 ```dart 192 ```dart
1178 Get.lazyPut<Service>(()=> ApiMock()); 193 Get.lazyPut<Service>(()=> ApiMock());
1179 /// ApiMock will only be called when someone uses Get.find<Service> for the first time 194 /// ApiMock will only be called when someone uses Get.find<Service> for the first time
1180 ``` 195 ```
1181 196
1182 -If you want to register an asynchronous instance, you can use Get.putAsync.  
1183 -```dart  
1184 -Get.putAsync<SharedPreferences>(() async {  
1185 - final prefs = await SharedPreferences.getInstance();  
1186 - await prefs.setInt('counter', 12345);  
1187 - return prefs;  
1188 -});  
1189 -```  
1190 -usage:  
1191 -  
1192 -```dart  
1193 - int count = Get.find<SharedPreferences>().getInt('counter');  
1194 - print(count);  
1195 - // out: 12345  
1196 -}  
1197 -```  
1198 -  
1199 -To remove a instance of Get:  
1200 -```dart  
1201 -Get.delete<Controller>();  
1202 -``` 197 +### In-depth explanation
1203 198
  199 +**See a more in-depth explanation of dependency management [here](./docs/en_US/dependency_management.md)**
1204 200
1205 -## Bindings  
1206 -One of the great differentials of this package, perhaps, is the possibility of full integration of the routes, state manager and dependency manager.  
1207 -When a route is removed from the Stack, all controllers, variables, and instances of objects related to it are removed from memory. If you are using streams or timers, they will be closed automatically, and you don't have to worry about any of that.  
1208 -In version 2.10 Get completely implemented the Bindings API.  
1209 -Now you no longer need to use the init method. You don't even have to type your controllers if you don't want to. You can start your controllers and services in the appropriate place for that.  
1210 -The Binding class is a class that will decouple dependency injection, while "binding" routes to the state manager and dependency manager.  
1211 -This allows Get to know which screen is being displayed when a particular controller is used and to know where and how to dispose of it.  
1212 -In addition, the Binding class will allow you to have SmartManager configuration control. You can configure the dependencies to be arranged when removing a route from the stack, or when the widget that used it is laid out, or neither. You will have intelligent dependency management working for you, but even so, you can configure it as you wish. 201 +# How to contribute
1213 202
1214 -### How to use  
1215 -- Create a class and implements Binding  
1216 -  
1217 -```dart  
1218 -class HomeBinding implements Bindings{  
1219 -```  
1220 -  
1221 -Your IDE will automatically ask you to override the "dependencies" method, and you just need to click on the lamp, override the method, and insert all the classes you are going to use on that route:  
1222 -  
1223 -```dart  
1224 -class HomeBinding implements Bindings{  
1225 - @override  
1226 - void dependencies() {  
1227 - Get.lazyPut<ControllerX>(() => ControllerX());  
1228 - Get.lazyPut<Service>(()=> Api());  
1229 - }  
1230 -}  
1231 -```  
1232 -Now you just need to inform your route, that you will use that binding to make the connection between route manager, dependencies and states.  
1233 -  
1234 -- Using named routes:  
1235 -```dart  
1236 -namedRoutes: {  
1237 - '/': GetRoute(Home(), binding: HomeBinding())  
1238 -}  
1239 -```  
1240 -  
1241 -- Using normal routes:  
1242 -```dart  
1243 -Get.to(Home(), binding: HomeBinding());  
1244 -```  
1245 -  
1246 -There, you don't have to worry about memory management of your application anymore, Get will do it for you.  
1247 -  
1248 -The Binding class is called when a route is called, you can create an "initialBinding in your GetMaterialApp to insert all the dependencies that will be created.  
1249 -```dart  
1250 -GetMaterialApp(  
1251 - initialBinding: SampleBind(),  
1252 - home: Home(),  
1253 -);  
1254 -```  
1255 -## SmartManagement  
1256 -Always prefer to use standard SmartManagement (full), you do not need to configure anything for that, Get already gives it to you by default. It will surely eliminate all your disused controllers from memory, as its refined control removes the dependency, even if a failure occurs and a widget that uses it is not properly disposed.  
1257 -The "full" mode is also safe enough to be used with StatelessWidget, as it has numerous security callbacks that will prevent a controller from remaining in memory if it is not being used by any widget, and disposition is not important here. However, if you are bothered by the default behavior, or just don't want it to happen, Get offers other, more lenient options for intelligent memory management, such as SmartManagement.onlyBuilders, which will depend on the effective removal of widgets using the controller. tree to remove it, and you can prevent a controller from being deployed using "autoRemove: false" in your GetBuilder/GetX.  
1258 -With this option, only controllers started in "init:" or loaded into a Binding with "Get.lazyPut" will be disposed, if you use Get.put or any other approach, SmartManagement will not have permissions to exclude this dependency.  
1259 -With the default behavior, even widgets instantiated with "Get.put" will be removed, unlike SmartManagement.onlyBuilders.  
1260 -SmartManagement.keepFactory is like SmartManagement.full, with one difference. SmartManagement.full purges the factories from the premises, so that Get.lazyPut() will only be able to be called once and your factory and references will be self-destructing. SmartManagement.keepFactory will remove its dependencies when necessary, however, it will keep the "shape" of these, to make an equal one if you need an instance of that again.  
1261 -Instead of using SmartManagement.keepFactory you can use Bindings.  
1262 -Bindings creates transitory factories, which are created the moment you click to go to another screen, and will be destroyed as soon as the screen-changing animation happens. It is so little time that the analyzer will not even be able to register it. When you navigate to this screen again, a new temporary factory will be called, so this is preferable to using SmartManagement.keepFactory, but if you don't want to create Bindings, or want to keep all your dependencies on the same Binding, it will certainly help you . Factories take up little memory, they don't hold instances, but a function with the "shape" of that class you want. This is very little, but since the purpose of this lib is to get the maximum performance possible using the minimum resources, Get removes even the factories by default. Use whichever is most convenient for you.  
1263 -  
1264 -- NOTE: DO NOT USE SmartManagement.keepFactory if you are using multiple Bindings. It was designed to be used without Bindings, or with a single Binding linked in the GetMaterialApp's initialBinding. 203 +*Want to contribute to the project? We will be proud to highlight you as one of our collaborators. Here are some points where you can contribute and make Get (and Flutter) even better.*
1265 204
1266 -- NOTE2: Using Bindings is completely optional, you can use Get.put() and Get.find() on classes that use a given controller without any problem.  
1267 -However, if you work with Services or any other abstraction, I recommend using Bindings for a larger organization. 205 +- Helping to translate the readme into other languages.
  206 +- Adding documentation to the readme (not even half of Get's functions have been documented yet).
  207 +- Write articles or make videos teaching how to use Get (they will be inserted in the Readme and in the future in our Wiki).
  208 +- Offering PRs for code/tests.
  209 +- Including new functions.
1268 210
  211 +Any contribution is welcome!
1269 212
1270 # Utils 213 # Utils
1271 214
1272 ## Change Theme 215 ## Change Theme
  216 +
1273 Please do not use any higher level widget than GetMaterialApp in order to update it. This can trigger duplicate keys. A lot of people are used to the prehistoric approach of creating a "ThemeProvider" widget just to change the theme of your app, and this is definitely NOT necessary with Get. 217 Please do not use any higher level widget than GetMaterialApp in order to update it. This can trigger duplicate keys. A lot of people are used to the prehistoric approach of creating a "ThemeProvider" widget just to change the theme of your app, and this is definitely NOT necessary with Get.
1274 218
1275 You can create your custom theme and simply add it within Get.changeTheme without any boilerplate for that: 219 You can create your custom theme and simply add it within Get.changeTheme without any boilerplate for that:
1276 220
1277 -  
1278 ```dart 221 ```dart
1279 Get.changeTheme(ThemeData.light()); 222 Get.changeTheme(ThemeData.light());
1280 ``` 223 ```
@@ -1287,31 +230,11 @@ Get.changeTheme(Get.isDarkMode? ThemeData.light(): ThemeData.dark()); @@ -1287,31 +230,11 @@ Get.changeTheme(Get.isDarkMode? ThemeData.light(): ThemeData.dark());
1287 230
1288 When darkmode is activated, it will switch to the light theme, and when the light theme is activated, it will change to dark. 231 When darkmode is activated, it will switch to the light theme, and when the light theme is activated, it will change to dark.
1289 232
1290 -  
1291 If you want to know in depth how to change the theme, you can follow this tutorial on Medium that even teaches the persistence of the theme using Get: 233 If you want to know in depth how to change the theme, you can follow this tutorial on Medium that even teaches the persistence of the theme using Get:
1292 234
1293 - [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). 235 - [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).
1294 236
1295 -  
1296 -  
1297 -## Other Advanced APIs and Manual configurations  
1298 -GetMaterialApp configures everything for you, but if you want to configure Get Manually using advanced APIs.  
1299 -  
1300 -```dart  
1301 -MaterialApp(  
1302 - navigatorKey: Get.key,  
1303 - navigatorObservers: [GetObserver()],  
1304 -);  
1305 -```  
1306 -  
1307 -You will also be able to use your own Middleware within GetObserver, this will not influence anything.  
1308 -  
1309 -```dart  
1310 -MaterialApp(  
1311 - navigatorKey: Get.key,  
1312 - navigatorObservers: [GetObserver(MiddleWare.observer)], // Here  
1313 -);  
1314 -``` 237 +## Other Advanced APIs
1315 238
1316 ```dart 239 ```dart
1317 Get.arguments // give the current args from currentScreen 240 Get.arguments // give the current args from currentScreen
@@ -1348,8 +271,26 @@ Get.contextOverlay // Gives the context of the snackbar/dialog/bottomsheet in th @@ -1348,8 +271,26 @@ Get.contextOverlay // Gives the context of the snackbar/dialog/bottomsheet in th
1348 271
1349 ``` 272 ```
1350 273
  274 +### Optional Global Settings and Manual configurations
  275 +
  276 +GetMaterialApp configures everything for you, but if you want to configure Get Manually using advanced APIs.
  277 +
  278 +```dart
  279 +MaterialApp(
  280 + navigatorKey: Get.key,
  281 + navigatorObservers: [GetObserver()],
  282 +);
  283 +```
  284 +
  285 +You will also be able to use your own Middleware within GetObserver, this will not influence anything.
  286 +
  287 +```dart
  288 +MaterialApp(
  289 + navigatorKey: Get.key,
  290 + navigatorObservers: [GetObserver(MiddleWare.observer)], // Here
  291 +);
  292 +```
1351 293
1352 -### Optional Global Settings  
1353 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 294 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
1354 295
1355 ```dart 296 ```dart
@@ -1370,14 +311,15 @@ Get.config( @@ -1370,14 +311,15 @@ Get.config(
1370 ``` 311 ```
1371 312
1372 # Breaking changes from 2.0 313 # Breaking changes from 2.0
  314 +
1373 1- Rx types: 315 1- Rx types:
1374 -Before: StringX now: RxString 316 +Before: StringX now: RxString
1375 317
1376 -Before: IntX now: RxInt 318 +Before: IntX now: RxInt
1377 319
1378 -Before: MapX now: RxMax 320 +Before: MapX now: RxMax
1379 321
1380 -Before: ListX now: RxList 322 +Before: ListX now: RxList
1381 323
1382 Before: NumX now: RxNum 324 Before: NumX now: RxNum
1383 325
@@ -1385,9 +327,9 @@ Before: RxDouble now: RxDouble @@ -1385,9 +327,9 @@ Before: RxDouble now: RxDouble
1385 327
1386 RxController and GetBuilder now have merged, you no longer need to memorize which controller you want to use, just use GetxController, it will work for simple state management and for reactive as well. 328 RxController and GetBuilder now have merged, you no longer need to memorize which controller you want to use, just use GetxController, it will work for simple state management and for reactive as well.
1387 329
1388 -  
1389 -2- NamedRoutes 330 +2- NamedRoutes
1390 Before: 331 Before:
  332 +
1391 ```dart 333 ```dart
1392 GetMaterialApp( 334 GetMaterialApp(
1393 namedRoutes: { 335 namedRoutes: {
@@ -1395,7 +337,9 @@ GetMaterialApp( @@ -1395,7 +337,9 @@ GetMaterialApp(
1395 } 337 }
1396 ) 338 )
1397 ``` 339 ```
  340 +
1398 Now: 341 Now:
  342 +
1399 ```dart 343 ```dart
1400 GetMaterialApp( 344 GetMaterialApp(
1401 getPages: [ 345 getPages: [
@@ -1421,5 +365,20 @@ GetMaterialApp( @@ -1421,5 +365,20 @@ GetMaterialApp(
1421 ) 365 )
1422 ``` 366 ```
1423 367
1424 -  
1425 This library will always be updated and implementing new features. Feel free to offer PRs and contribute to them. 368 This library will always be updated and implementing new features. Feel free to offer PRs and contribute to them.
  369 +
  370 +# Why I made this package
  371 +
  372 +The problem that this package tries to solve is to have most of what you need in only one package. One day, when i update some of my apps to work with Flutter 1.9, something bad happened: Everything broke.
  373 +
  374 +All of my libraries broke down, the libraries started to be prevented from using hyphen "-". Some updated the package, others did not. The others I had to look for because the project did not compile. Other libs just became incompatible with the current version, such as the image_extended that I offered a PR there to be able to solve, and all because of a simple update.
  375 +
  376 +I lost 2 days of work just looking for errors to know where they came from and what lib they came from.
  377 +
  378 +I confess that it was one of the most stressful situations I have ever gone through in my life. It was exactly on that day that I decided to do everything in one package.
  379 +
  380 +I know this looks a lot like the package being based on my personal experiences, but I am a programmer, and I try to solve problems always from the programmer's perspective. I don't care about anything other than making my life and other devs easier with this library.
  381 +
  382 +Every time I go through a frustrating experience, I write it down in my schedule, and try to resolve it after completing the project.
  383 +
  384 +And then I decided to make a package that have the three things that you will always use: State management, route management, Dependency injection/management, internationalization, and storage (the last two are still being made)
@@ -11,81 +11,34 @@ @@ -11,81 +11,34 @@
11 11
12 <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> 12 <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>
13 13
  14 +- [Sobre Get](#sobre-get)
  15 + - [Instalando e iniciando](#instalando-e-iniciando)
  16 +- [Os três pilares](#os-três-pilares)
  17 + - [Gerenciamento de estado](#gerenciamento-de-estado)
  18 + - [Explicação completa](#explicação-completa)
  19 + - [Gerenciamento de rotas](#gerenciamento-de-rotas)
  20 + - [Explicação completa](#explicação-completa-1)
  21 + - [Gerenciamento de Dependência](#gerenciamento-de-dependência)
  22 + - [Explicação completa](#explicação-completa-2)
  23 +- [Utilidades](#utilidades)
  24 + - [Outras APIs avançadas e Configurações Manuais](#outras-apis-avançadas-e-configurações-manuais)
  25 +
  26 +# Sobre Get
  27 +
14 - Get é uma biblioteca poderosa e extra-leve para Flutter. Ela combina um gerenciador de estado de alta performance, injeção de dependência inteligente e gerenciamento de rotas de uma forma rápida e prática. 28 - Get é uma biblioteca poderosa e extra-leve para Flutter. Ela combina um gerenciador de estado de alta performance, injeção de dependência inteligente e gerenciamento de rotas de uma forma rápida e prática.
15 - Get não é para todos, seu foco é 29 - Get não é para todos, seu foco é
16 - **Performance**: Já que gasta o mínimo de recursos 30 - **Performance**: Já que gasta o mínimo de recursos
17 - **Produtividade**: Usando uma sintaxe fácil e agradável 31 - **Produtividade**: Usando uma sintaxe fácil e agradável
18 - **Organização**: Que permite o total desacoplamento da View e da lógica de negócio. 32 - **Organização**: Que permite o total desacoplamento da View e da lógica de negócio.
19 -- Get vai economizar horas de desenvolvimento, e vai extrair a performance máxima que sua aplicação pode entregar, enquanto é fácil para iniciantes e preciso para experts.  
20 -- Navegue por rotas sem `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. 33 +- Get vai economizar horas de desenvolvimento, e vai extrair a performance máxima que sua aplicação pode entregar, enquanto é fácil para iniciantes e preciso para experts.
  34 +- Navegue por rotas sem `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.
21 - Get é seguro, estável, atualizado e oferece uma enorme gama de APIs que não estão presentes no framework padrão. 35 - Get é seguro, estável, atualizado e oferece uma enorme gama de APIs que não estão presentes no framework padrão.
  36 +- GetX não é um `bloc` da vida. Ele tem uma variedade de recursos que te permite começar a programar sem se preocupar com nada, mas cada um desses recursos estão em um container separado, ou seja, nenhuma depende da outra para funcionar. Elas só são inicializadas após o uso. Se você usa apenas o gerenciador de estado, apenas ele será compilado. Teste você mesmo, vá no repositório de benchmark do getX e perceberá: usando somente o gerenciador de estado do Get, a aplicação ficou mais leve do que outros projetos que também estão usando só o gerenciador de estado, porque nada que não seja usado será compilado no seu código, e cada recuro do GetX foi feito para ser muito leve. O mérito vem também do AOT do próprio Flutter que é incrível, e consegue eliminar recursos não utilizados de uma forma que nenhum outro framework consegue.
22 37
23 -**O app 'Counter' criado por padrão no com o comando `flutter create` tem mais de 100 linhas(incluindo os comentários). Para demonstrar o poder do Get, irei demonstrar como fazer o mesmo 'Counter' mudando o estado em cada toque trocando entre páginas e compartilhando o estado entre telas. Tudo de forma organizada, separando a lógica de negócio da View, COM SOMENTE 26 LINHAS INCLUINDO COMENTÁRIOS** 38 +**GetX faz seu desenvolvimento mais produtivo, mas quer deixá-lo mais produtivo ainda? Adicione a extensão [GetX extension to VSCode](https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets) no seu VSCode**. Não disponível para outras IDEs por enquanto.
24 39
25 -```dart  
26 -void main() => runApp(GetMaterialApp(home: Home()));  
27 -// Crie sua classe de lógica de negócio e coloque todas as variáveis, métodos e controllers dentro dela  
28 -class Controller extends RxController {  
29 - // ".obs" transforma um objeto num Observable  
30 - var count = 0.obs;  
31 - increment() => count.value++;  
32 -} 40 +Quer contribuir no projeto? Nós ficaremos orgulhosos de ressaltar você como um dos colaboradores. Aqui vai algumas formas em que você pode contribuir e fazer Get (e Flutter) ainda melhores
33 41
34 -class Home extends StatelessWidget {  
35 - // Instancie sua classe usando Get.put() para torná-la disponível para todas as rotas subsequentes  
36 - final Controller c = Get.put(Controller());  
37 - @override  
38 - Widget build(context) => Scaffold(  
39 - appBar: AppBar(title: Obx(  
40 - () => Text("Total of clicks: " + c.count.string))),  
41 - // Troque o Navigator.push de 8 linhas por um simples Get.to(). Você não precisa do 'context'  
42 - body: Center(child: RaisedButton(  
43 - child: Text("Ir pra Outra tela"), onPressed: () => Get.to(Outra()))),  
44 - floatingActionButton: FloatingActionButton(child:  
45 - Icon(Icons.add), onPressed: c.increment));  
46 -}  
47 -  
48 -class Outra extends StatelessWidget {  
49 - // Você pode pedir o Get para encontrar o controller que foi usado em outra página e redirecionar você pra ele.  
50 - final Controller c = Get.find();  
51 - @override  
52 - Widget build(context) => Scaffold(body: Center(child: Text(c.count.string)));  
53 -}  
54 -  
55 -```  
56 -  
57 -Esse é um projeto simples mas já deixa claro o quão poderoso o Get é. Enquanto seu projeto cresce, essa diferença se torna bem mais significante.  
58 -  
59 -Get foi feito para funcionar com times, mas torna o trabalho de um desenvolvedor individual simples.  
60 -  
61 -Melhore seus prazos, entregue tudo a tempo sem perder performance. Get não é para todos, mas se você identificar com o que foi dito acima, Get é para você!  
62 -  
63 -- [Como usar?](#como-usar)  
64 -- [Navegação sem rotas nomeadas](#navegação-sem-rotas-nomeadas)  
65 - - [SnackBars](#snackbars)  
66 - - [Dialogs](#dialogs)  
67 - - [BottomSheets](#bottomsheets)  
68 -- [Gerenciador de estado simples](#gerenciador-de-estado-simples)  
69 - - [Uso do gerenciador de estado simples](#uso-do-gerenciador-de-estado-simples)  
70 - - [Sem StatefulWidget;](#sem-statefulwidget)  
71 - - [Formas de uso:](#formas-de-uso)  
72 -- [Reactive State Manager](#reactive-state-manager)  
73 - - [GetX vs GetBuilder vs Obx vs MixinBuilder](#getx-vs-getbuilder-vs-obx-vs-mixinbuilder)  
74 -- [Gerenciamento de dependências simples](#gerenciamento-de-dependências-simples)  
75 -- [Bindings](#bindings)  
76 - - [Como utilizar:](#como-utilizar)  
77 -- [Workers](#workers)  
78 -- [Navegar com rotas nomeadas](#navegar-com-rotas-nomeadas)  
79 - - [Enviar dados para rotas nomeadas](#enviar-dados-para-rotas-nomeadas)  
80 - - [Links de Url dinâmicos](#links-de-url-dinâmicos)  
81 - - [Middleware](#middleware)  
82 - - [Change Theme](#change-theme)  
83 - - [Configurações Globais Opcionais](#configurações-globais-opcionais)  
84 -  
85 -  
86 -  
87 -  
88 -#### Quer contribuir no projeto? Nós ficaremos orgulhosos de ressaltar você como um dos colaboradores. Aqui vai algumas formas em que você pode contribuir e fazer Get (e Flutter) ainda melhores:  
89 - Ajudando a traduzir o README para outras linguagens. 42 - Ajudando a traduzir o README para outras linguagens.
90 - Adicionando mais documentação ao README (até o momento, nem metade das funcionalidades do Get foram documentadas). 43 - Adicionando mais documentação ao README (até o momento, nem metade das funcionalidades do Get foram documentadas).
91 - Fazendo artigos/vídeos ensinando a usar o Get (eles serão inseridos no README, e no futuro na nossa Wiki). 44 - Fazendo artigos/vídeos ensinando a usar o Get (eles serão inseridos no README, e no futuro na nossa Wiki).
@@ -94,19 +47,21 @@ Melhore seus prazos, entregue tudo a tempo sem perder performance. Get não é p @@ -94,19 +47,21 @@ Melhore seus prazos, entregue tudo a tempo sem perder performance. Get não é p
94 47
95 Qualquer contribuição é bem-vinda! 48 Qualquer contribuição é bem-vinda!
96 49
97 -## Como usar? 50 +## Instalando e iniciando
98 51
99 <!-- - Flutter Master/Dev/Beta: version 2.0.x-dev 52 <!-- - Flutter Master/Dev/Beta: version 2.0.x-dev
100 - Flutter Stable branch: version 2.0.x 53 - Flutter Stable branch: version 2.0.x
101 (procure pela versão mais recente em pub.dev) --> 54 (procure pela versão mais recente em pub.dev) -->
102 55
103 Adicione Get ao seu arquivo pubspec.yaml 56 Adicione Get ao seu arquivo pubspec.yaml
  57 +
104 ```yaml 58 ```yaml
105 dependencies: 59 dependencies:
106 get: 60 get:
107 ``` 61 ```
108 62
109 Troque seu `MaterialApp()` por `GetMaterialApp()` e aproveite! 63 Troque seu `MaterialApp()` por `GetMaterialApp()` e aproveite!
  64 +
110 ```dart 65 ```dart
111 import 'package:get/get.dart'; 66 import 'package:get/get.dart';
112 67
@@ -115,621 +70,117 @@ GetMaterialApp( // Antes: MaterialApp( @@ -115,621 +70,117 @@ GetMaterialApp( // Antes: MaterialApp(
115 ) 70 )
116 ``` 71 ```
117 72
118 -## Navegação sem rotas nomeadas  
119 -  
120 -Para navegar para uma próxima tela:  
121 -```dart  
122 -Get.to(ProximaTela());  
123 -```  
124 -  
125 -Para fechar snackbars, dialogs, bottomsheets, ou qualquer coisa que você normalmente fecharia com o `Navigator.pop(context)` (como por exemplo fechar a View atual e voltar para a anterior):  
126 -```dart  
127 -Get.back();  
128 -```  
129 -  
130 -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.):  
131 -```dart  
132 -Get.off(ProximaTela());  
133 -```  
134 -  
135 -Para ir para a próxima tela e cancelar todas as rotas anteriores (útil em telas de carrinho, votações ou testes): 73 +# Os três pilares
136 74
137 -```dart  
138 -Get.offAll(ProximaTela());  
139 -```  
140 -  
141 -Para navegar para a próxima rota, e receber ou atualizar dados assim que retornar da rota:  
142 -```dart  
143 -var dados = await Get.to(Pagamento());  
144 -```  
145 -Na outra tela, envie os dados para a rota anterior:  
146 -  
147 -```dart  
148 -Get.back(result: 'sucesso');  
149 -```  
150 -E use-os:  
151 -  
152 -```dart  
153 -if (dados == 'sucesso') fazerQualquerCoisa();  
154 -```  
155 -  
156 -Não quer aprender nossa sintaxe?  
157 -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`  
158 -  
159 -Exemplo:  
160 -```dart  
161 -// Navigator padrão do Flutter  
162 -Navigator.of(context).push(  
163 - context,  
164 - MaterialPageRoute(  
165 - builder: (BuildContext context) {  
166 - return HomePage();  
167 - },  
168 - ),  
169 -);  
170 -  
171 -// Get usando a sintaxe Flutter sem precisar do context  
172 -navigator.push(  
173 - MaterialPageRoute(  
174 - builder: (_) {  
175 - return HomePage();  
176 - },  
177 - ),  
178 -);  
179 -  
180 -// Sintaxe do Get (é bem melhor, mas você tem o direito de discordar)  
181 -Get.to(HomePage());  
182 -```  
183 -  
184 -### SnackBars  
185 -  
186 -Para ter um `SnackBar` simples no Flutter, você precisa do `context` do Scaffold, ou uma `GlobalKey` atrelada ao seu Scaffold.  
187 -```dart  
188 -final snackBar = SnackBar(  
189 - content: Text('Olá!'),  
190 - action: SnackBarAction(  
191 - label: 'Eu sou uma SnackBar velha e feia :(',  
192 - onPressed: (){}  
193 - ),  
194 -);  
195 -// Encontra o Scaffold na árvore de Widgets e  
196 -// o usa para mostrar o SnackBar  
197 -Scaffold.of(context).showSnackBar(snackBar);  
198 -```  
199 -  
200 -Com o Get:  
201 -```dart  
202 -Get.snackbar('Olá', 'eu sou uma SnackBar moderna e linda!');  
203 -```  
204 -  
205 -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!  
206 -  
207 -```dart  
208 -Get.snackbar(  
209 - "Ei, eu sou uma SnackBar Get!", // título  
210 - "É inacreditável! Eu estou usando uma SnackBar sem context, sem boilerplate, sem Scaffold!", // mensagem  
211 - icon: Icon(Icons.alarm),  
212 - shouldIconPulse: true,  
213 - onTap:(){},  
214 - barBlur: 20,  
215 - isDismissible: true,  
216 - duration: Duration(seconds: 3),  
217 -);  
218 -  
219 -  
220 - ////////// TODOS OS RECURSOS //////////  
221 - // Color colorText,  
222 - // Duration duration,  
223 - // SnackPosition snackPosition,  
224 - // Widget titleText,  
225 - // Widget messageText,  
226 - // bool instantInit,  
227 - // Widget icon,  
228 - // bool shouldIconPulse,  
229 - // double maxWidth,  
230 - // EdgeInsets margin,  
231 - // EdgeInsets padding,  
232 - // double borderRadius,  
233 - // Color borderColor,  
234 - // double borderWidth,  
235 - // Color backgroundColor,  
236 - // Color leftBarIndicatorColor,  
237 - // List<BoxShadow> boxShadows,  
238 - // Gradient backgroundGradient,  
239 - // FlatButton mainButton,  
240 - // OnTap onTap,  
241 - // bool isDismissible,  
242 - // bool showProgressIndicator,  
243 - // AnimationController progressIndicatorController,  
244 - // Color progressIndicatorBackgroundColor,  
245 - // Animation<Color> progressIndicatorValueColor,  
246 - // SnackStyle snackStyle,  
247 - // Curve forwardAnimationCurve,  
248 - // Curve reverseAnimationCurve,  
249 - // Duration animationDuration,  
250 - // double barBlur,  
251 - // double overlayBlur,  
252 - // Color overlayColor,  
253 - // Form userInputForm  
254 - ///////////////////////////////////  
255 -```  
256 -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.  
257 -  
258 -### Dialogs  
259 -  
260 -Para abrir um dialog:  
261 -```dart  
262 -Get.dialog(SeuWidgetDialog());  
263 -```  
264 -  
265 -Para abrir um dialog padrão:  
266 -```dart  
267 -Get.defaultDialog(  
268 - onConfirm: () => print("Ok"),  
269 - middleText: "Dialog made in 3 lines of code",  
270 -);  
271 -```  
272 -Você também pode usar `Get.generalDialog` em vez de `showGeneralDialog`. 75 +## Gerenciamento de estado
273 76
274 -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. 77 +Veja uma explicação mais completa do gerenciamento de estado [aqui](./docs/pt_BR/route_management.md)
275 78
276 -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. 79 +O app 'Counter' criado por padrão no com o comando `flutter create` tem mais de 100 linhas(incluindo os comentários). Para demonstrar o poder do Get, irei demonstrar como fazer o mesmo 'Counter' mudando o estado em cada toque trocando entre páginas e compartilhando o estado entre telas. Tudo de forma organizada, separando a lógica de negócio da View, COM SOMENTE 26 LINHAS INCLUINDO COMENTÁRIOS
277 80
278 -### BottomSheets  
279 -`Get.bottomSheet()` é tipo o `showModalBottomSheet()`, mas não precisa do context. 81 +- Passo 1:
  82 +Troque `MaterialApp` para `GetMaterialApp`
280 83
281 ```dart 84 ```dart
282 -Get.bottomSheet(  
283 - Container(  
284 - child: Wrap(  
285 - children: <Widget>[  
286 - ListTile(  
287 - leading: Icon(Icons.music_note),  
288 - title: Text('Música'),  
289 - onTap: () => {}  
290 - ),  
291 - ListTile(  
292 - leading: Icon(Icons.videocam),  
293 - title: Text('Vídeo'),  
294 - onTap: () => {},  
295 - ),  
296 - ],  
297 - ),  
298 - ),  
299 -); 85 +void main() => runApp(GetMaterialApp(home: Home()));
300 ``` 86 ```
301 87
302 -## Gerenciador de estado simples  
303 -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.  
304 -  
305 -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.  
306 -  
307 -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.  
308 -  
309 -**Que melhoras na performance o Get traz?**  
310 -  
311 -1. Atualiza somente o widget necessário.  
312 -  
313 -2. Não usa o `ChangeNotifier`, é o gerenciador de estado que utiliza menos memória (próximo de 0mb até agora).  
314 -  
315 -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.  
316 -  
317 -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.  
318 -  
319 -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.  
320 -  
321 -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.  
322 -  
323 -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)  
324 -  
325 -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ó.  
326 -  
327 -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.  
328 -  
329 -Vamos analisar o seguite exemplo:  
330 -  
331 -`Class A => Class B (ControllerX) => Class C (ControllerX)`  
332 -  
333 -* Na classe A o controller não está ainda na memória, porque você ainda não o usou (Get carrega só quando precisa).  
334 -  
335 -* Na classe B você usou o controller, e ele entrou na memória.  
336 -  
337 -* 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.  
338 -  
339 -* 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.  
340 -  
341 -* Se você navegar para a Classe B denovo, o controller X vai entrar na memória denovo.  
342 -  
343 -* 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.  
344 -  
345 -* 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.  
346 -  
347 -**Nota**: A única exceção que pode atrapalhar o Get, é se  
348 -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. 88 +- **Obs:** Isso não modifica o `MaterialApp` do Flutter, GetMaterialApp não é uma versão modificada do MaterialApp, é só um Widget pré-configurado, que tem como child o MaterialApp padrão. Você pode configurar isso manualmente, mas definitivamente não é necessário. GetMaterialApp vai criar rotas, injetá-las, injetar traduções, injetar tudo que você precisa para navegação por rotas (gerenciamento de rotas). Se você quer somente usar o gerenciado de estado ou somente o gerenciador de dependências, não é necessário usar o GetMaterialApp. Ele somente é necessário para:
  89 + - Rotas
  90 + - Snackbars/bottomsheets/dialogs
  91 + - apis relacionadas a rotas e a ausência de `context`
349 92
350 -### Uso do gerenciador de estado simples 93 +- Passo 2:
  94 +Cria a sua classe de regra de negócio e coloque todas as variáveis, métodos e controllers dentro dela.
  95 +Você pode fazer qualquer variável observável usando um simples `.obs`
351 96
352 ```dart 97 ```dart
353 -// Crie a classe Controller e entenda ela do GetController  
354 -class Controller extends GetController {  
355 - int counter = 0;  
356 - void increment() {  
357 - counter++;  
358 - update(); // use update() para atualizar a variável counter na UI quando increment for chamado  
359 - } 98 +class Controller extends GetxController{
  99 + var count = 0.obs;
  100 + increment() => count.value++;
360 } 101 }
361 -// Na sua classe Stateless/Stateful, use o GetBuilder para atualizar o texto quando a função increment for chamada  
362 -GetBuilder<Controller>(  
363 - init: Controller(), // INICIE O CONTROLLER SOMENTE NA PRIMEIRA VEZ  
364 - builder: (controller) => Text(  
365 - '${controller.counter}',  
366 - ),  
367 -),  
368 -// 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.  
369 ``` 102 ```
370 -**Feito!**  
371 -  
372 -Você já aprendeu como gerenciar estados com o Get.  
373 103
374 -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.  
375 -  
376 -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): 104 +- Passo 3:
  105 +Crie sua View usando StatelessWidget, já que, usando Get, você não precisa mais usar StatefulWidgets.
377 106
378 ```dart 107 ```dart
379 -class OutraClasse extends StatelessWidget { 108 +class Home extends StatelessWidget {
  109 + // Instancie sua classe usando Get.put() para torná-la disponível para todas as rotas subsequentes
  110 + final Controller c = Get.put(Controller());
380 @override 111 @override
381 - Widget build(BuildContext context) {  
382 - return Scaffold(  
383 - body: Center(  
384 - child: GetBuilder<Controller>(  
385 - builder: (s) => Text('${s.counter}'),  
386 - ),  
387 - ),  
388 - );  
389 - }  
390 -}  
391 -```  
392 -  
393 -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>()` )  
394 -  
395 -```dart  
396 -class Controller extends GetController {  
397 -  
398 - /// Você não precisa disso. Eu recomendo usar isso apenas  
399 - /// porque a sintaxe é mais fácil.  
400 - /// com o método estático: Controller.to.counter();  
401 - /// sem o método estático: Get.find<Controller>();  
402 - /// 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.  
403 - static Controller get to => Get.find(); // adicione esta linha  
404 -  
405 - int counter = 0;  
406 - void increment() {  
407 - counter++;  
408 - update();  
409 - }  
410 -}  
411 -```  
412 -E então você pode acessar seu controller diretamente, desse jeito:  
413 -```dart  
414 -FloatingActionButton(  
415 - onPressed:(){  
416 - Controller.to.increment(),  
417 - } // Isso é incrivelmente simples!  
418 - child: Text("${Controller.to.counter}"),  
419 -),  
420 -```  
421 -Quando você pressionar o FloatingActionButton, todos os widgets que estão escutando a variável `counter` serão atualizados automaticamente.  
422 -  
423 -#### Sem StatefulWidget;  
424 -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.  
425 -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!  
426 -  
427 -A não ser que você precise usar um mixin, como o `TickerProviderStateMixin`, será totalmente desnecessário usar um StatefulWidget com o Get.  
428 -  
429 -Você pode chamar todos os métodos de um StatefulWidget diretamente de um GetBuilder.  
430 -Se você precisa chamar o método `initState()` ou `dispose()` por exemplo, é possível chamá-los diretamente:  
431 -```dart  
432 -GetBuilder<Controller>(  
433 - initState: (_) => Controller.to.fetchApi(),  
434 - dispose: (_) => Controller.to.closeStreams(),  
435 - builder: (s) => Text('${s.username}'),  
436 -),  
437 -```  
438 -Uma abordagem muito melhor que isso é usar os métodos `onInit()` e `onClose()` diretamente do seu controller.  
439 -  
440 -```dart  
441 -@override  
442 -void onInit() {  
443 - fetchApi();  
444 - super.onInit(); 112 + Widget build(context) => Scaffold(
  113 + appBar: AppBar(title: Obx(
  114 + () => Text("Total of clicks: " + c.count.string))),
  115 + // Troque o Navigator.push de 8 linhas por um simples Get.to(). Você não precisa do 'context'
  116 + body: Center(child: RaisedButton(
  117 + child: Text("Ir pra Outra tela"), onPressed: () => Get.to(Outra()))),
  118 + floatingActionButton: FloatingActionButton(child:
  119 + Icon(Icons.add), onPressed: c.increment));
445 } 120 }
446 -```  
447 -* 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()`.  
448 -  
449 -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.  
450 -  
451 -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.  
452 -  
453 -Então, para simplificar isso:  
454 -  
455 -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.  
456 -  
457 -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.  
458 121
459 -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()`.  
460 -  
461 -Exemplo:  
462 -```dart  
463 -class Controller extends GetController {  
464 - var user = StreamController<User>();  
465 - var name = StreamController<String>();  
466 -  
467 - /// fechar stream = método onClose(), não dispose(). 122 +class Outra extends StatelessWidget {
  123 + // Você pode pedir o Get para encontrar o controller que foi usado em outra página e redirecionar você pra ele.
  124 + final Controller c = Get.find();
468 @override 125 @override
469 - void onClose() {  
470 - user.close();  
471 - name.close();  
472 - super.onClose();  
473 - }  
474 -}  
475 -```  
476 -Ciclo de vida do controller:  
477 -* `onInit()`: Onde ele é criado.  
478 -* `onClose()`: Onde ele é fechado para fazer mudanças em preparação para o método delete()  
479 -* 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.  
480 -  
481 -##### Formas de uso:  
482 -  
483 -Você pode usar uma instância do Controller diretamente no `value` do GetBuilder  
484 -  
485 -```dart  
486 -GetBuilder<Controller>(  
487 - init: Controller(),  
488 - builder: (value) => Text(  
489 - '${value.counter}', //aqui  
490 - )  
491 -),  
492 -```  
493 -Você talvez também precise de uma instância do seu controller fora do GetBuilder, e você pode usar essas abordagens para conseguir isso:  
494 -  
495 -essa:  
496 -```dart  
497 -class Controller extends GetController {  
498 - static Controller get to => Get.find(); // criando um getter estático  
499 - [...]  
500 -}  
501 -// Na sua view/tela  
502 -GetBuilder<Controller>(  
503 - init: Controller(), // use somente uma vez por controller, não se esqueça  
504 - builder: (_) => Text(  
505 - '${Controller.to.counter}', //aqui  
506 - )  
507 -),  
508 -```  
509 -  
510 -ou essa:  
511 -```dart  
512 -class Controller extends GetController {  
513 - // sem nenhum método estático  
514 -[...] 126 + Widget build(context) => Scaffold(body: Center(child: Text(c.count.string)));
515 } 127 }
516 -// Numa classe stateful/stateless  
517 -GetBuilder<Controller>(  
518 - init: Controller(), // use somente uma vez por controller, não se esqueça  
519 - builder: (_) => Text(  
520 - '${Get.find<Controller>().counter}', //aqui  
521 - )  
522 -),  
523 -```  
524 -  
525 -* 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:  
526 -  
527 -```dart  
528 -Controller controller = Controller();  
529 -[...]  
530 -GetBuilder<Controller>(  
531 - init: controller, //aqui  
532 - builder: (_) => Text(  
533 - '${controller.counter}', // aqui  
534 - )  
535 -),  
536 128
537 ``` 129 ```
538 130
539 -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!  
540 -  
541 -Se você quiser refinar o controle de atualização de widgets do GetBuilder, você pode assinalar a ele IDs únicas  
542 -```dart  
543 -GetBuilder<Controller>(  
544 - id: 'text'  
545 - init: Controller(), // use somente uma vez por controller, não se esqueça  
546 - builder: (_) => Text(  
547 - '${Get.find<Controller>().counter}', //aqui  
548 - )  
549 -),  
550 -```  
551 -E atualizá-los dessa forma:  
552 -```dart  
553 -update(['text']);  
554 -```  
555 -  
556 -Você também pode impor condições para o update acontecer:  
557 -```dart  
558 -update(['text'], counter < 10);  
559 -```  
560 -  
561 -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).  
562 -  
563 -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. 131 +Esse é um projeto simples mas já deixa claro o quão poderoso o Get é. Enquanto seu projeto cresce, essa diferença se torna bem mais significante.
564 132
565 -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. 133 +Get foi feito para funcionar com times, mas torna o trabalho de um desenvolvedor individual simples.
566 134
567 -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()`. 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.  
568 -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. 135 +Melhore seus prazos, entregue tudo a tempo sem perder performance. Get não é para todos, mas se você identificar com o que foi dito acima, Get é para você!
569 136
570 -## Reactive State Manager 137 +### Explicação completa
571 138
572 -Se você quer poder, Get té dá o mais avançado gerenciador de estado que você pode ter.  
573 -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.  
574 -Sem decorations, você poder tornar qualquer coisa em um `Observable` com somete um `.obs` 139 +**Veja uma explicação mais completa do gerenciamento de estado [aqui](./docs/pt_BR/state_management.md)**
575 140
576 -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. 141 +## Gerenciamento de rotas
577 142
578 -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: 143 +Veja uma explicação mais completa do gerenciamento de estado [aqui](./docs/pt_BR/route_management.md)
579 144
580 -```dart  
581 -final count1 = 0.obs;  
582 -final count2 = 0.obs;  
583 -int get sum => count1.value + count2.value;  
584 -``` 145 +Para navegar para uma próxima tela:
585 146
586 ```dart 147 ```dart
587 -GetX<Controller>(  
588 - builder: (_) {  
589 - print("count 1 foi reconstruído");  
590 - return Text('${_.count1.value}');  
591 - },  
592 -),  
593 -GetX<Controller>(  
594 - builder: (_) {  
595 - print("count 2 foi reconstruído");  
596 - return Text('${_.count2.value}');  
597 - },  
598 -),  
599 -GetX<Controller>(  
600 - builder: (_) {  
601 - print("sum foi reconstruído");  
602 - return Text('${_.sum}');  
603 - },  
604 -), 148 +Get.to(ProximaTela());
605 ``` 149 ```
606 -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`.  
607 -  
608 -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.  
609 -  
610 -Se definirmos o valor de `count1` para 1, nenhum widget será reconstruído, porque o valor já era 1.  
611 150
612 -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.  
613 -  
614 -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). 151 +Para fechar snackbars, dialogs, bottomsheets, ou qualquer coisa que você normalmente fecharia com o `Navigator.pop(context)` (como por exemplo fechar a View atual e voltar para a anterior):
615 152
616 ```dart 153 ```dart
617 -list.addIf(item < limit, item); 154 +Get.back();
618 ``` 155 ```
619 156
620 -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! 157 +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.):
621 158
622 -Sabe o app de contador do Flutter? Sua classe Controller pode ficar assim:  
623 ```dart 159 ```dart
624 -class CountController extends RxController {  
625 - final count = 0.obs;  
626 -}  
627 -```  
628 -E com um simples:  
629 -```dart  
630 -controller.count.value++ 160 +Get.off(ProximaTela());
631 ``` 161 ```
632 162
633 -Você pode atualizar a variável counter na sua UI, independente de onde esteja sendo armazenada.  
634 -  
635 -Você pode transformar qualquer coisa em obs:  
636 -```dart  
637 -class RxUsuario {  
638 - final nome = "Camila".obs;  
639 - final idade = 18.obs;  
640 -}  
641 -  
642 -class Usuario {  
643 - Usuario({String nome, int idade});  
644 - final rx = RxUsuario();  
645 -  
646 - String get nome => rx.nome.value;  
647 - set nome(String value) => rx.nome.value = value;  
648 -  
649 - int get idade => rx.idade.value;  
650 - set idade(int value) => rx.idade.value = value;  
651 -}  
652 -``` 163 +Para ir para a próxima tela e cancelar todas as rotas anteriores (útil em telas de carrinho, votações ou testes):
653 164
654 ```dart 165 ```dart
655 -  
656 -void main() {  
657 - final usuario = Usuario();  
658 - print(usuario.nome);  
659 - usuario.idade = 23;  
660 - usuario.rx.idade.listen((int idade) => print(idade));  
661 - usuario.idade = 24;  
662 - usuario.idade = 25;  
663 -}  
664 -___________  
665 -saída:  
666 -Camila  
667 -23  
668 -24  
669 -25 166 +Get.offAll(ProximaTela());
670 ``` 167 ```
671 168
672 -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. 169 +Para navegar para a próxima rota, e receber ou atualizar dados assim que retornar da rota:
673 170
674 -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.  
675 ```dart 171 ```dart
676 -final list = List<Usuario>().obs;  
677 -  
678 -ListView.builder (  
679 -itemCount: list.lenght  
680 -) 172 +var dados = await Get.to(Pagamento());
681 ``` 173 ```
682 174
683 -Você não precisa trabalhar com sets se não quiser. Você pode usar as APIs `assign` e `assignAll`  
684 -  
685 -A api `assign` vai limpar sua lista e adicionar um único objeto que você quer.  
686 -  
687 -A api `assignAll` vai limpar sua lista e vai adicionar objetos `Iterable` que você precisa.  
688 -  
689 -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.  
690 -  
691 -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.  
692 -  
693 -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.  
694 -  
695 -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.  
696 -  
697 -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.  
698 -  
699 -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.  
700 -  
701 -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.  
702 -  
703 -### GetX vs GetBuilder vs Obx vs MixinBuilder  
704 -  
705 -Em uma década de trabalho com programação eu fui capaz de aprender umas lições valiosas.  
706 -  
707 -Meu primeiro contato com programação reactiva foi tão "Nossa, isso é incrível" e de fato é incrível.  
708 -  
709 -Porém, não é ideal para todas as situações. De vez em quando tudo que você precisa é mudar o estado de duas ou três variáveis ao mesmo tempo, ou uma mudança de estado diferente, que nesses casos a programação reativa não é ruim, mas não é apropriado.  
710 -  
711 -Programação reativa tem um consumo de RAM maior que pode ser compensado pelo fluxo individual, que vai se encarregar que apenas o Widget necessário é reconstruído, mas criar uma lista com 80 objetos, cada um com vários streams não é uma boa ideia. Abra o `dart inspect` e cheque quando um StreamBuilder consome, e você vai entender o que eu estou tentando dizer a você.  
712 -  
713 -Com isso em mente, eu criar o gerenciador de estados simples. É simples, e é exatamente o que você deve exigir dele: alterar vários estados em blocos de uma forma simples, e mais econômico possível.  
714 -  
715 -GetBuilder economiza muito quando se trata de RAM, e dificilmente vai existir uma forma mais econômica de lidar com isso do que ele (pelo menos eu não consigo imaginar nenhum. Se existir, me avise).  
716 -  
717 -Entretando, GetBuilder ainda é um gerenciador de estados "mecânico", você precisa chamar o `update()` assim como você faria com o `notifyListeners()` do `Provider`.  
718 -  
719 -Há outras situações onde a programação reativa é muito interessante, e não trabalhar com ela é a mesma coisa que reinventar a roda. Com isso em mente, GetX foi criado para prover tudo que há de mais moder e avançado num gerenciado de estado. Ele atualiza somente o que é necessário quando for necessário. Se por exemplo você tiver um erro que mande 300 alterações de estado simultaneamente, GetX vai filtrar e alterar a tela somente se o estado mudar de verdade. 175 +### Explicação completa
720 176
721 -GetX ainda é mais econômico que qualquer outro gerenciador de estados reativo, mas consome um pouco mais de RAM do que o GetBuilder. Pensando nisso e mirando em minimizar o consumo de recursos que o Obx foi criado. 177 +**GetX funciona com rotas nomeadas também! Veja uma explicação mais completa do gerenciamento de rotas [aqui](./docs/pt_BR/route_management.md)**
722 178
723 -Ao contrário de GetX e GetBuilder, você não será capaz de inicializar o controller dentro do Obx, é só um Widget com um `StreamSubscription` que recebe eventos de mundança das childrens ou child, só isso. É mais econômico que o GetX, mas perde para o GetBuilder, que é nada mais que o esperado, já que é reativo. GetBuilder tem uma das formas mais simplística que existe, de guardar o hashcode de um Widget e seu StateSetter. Com Obs você não precisa escrever seu tipo de controller, e você pode ouvir mudanças de múltiplos controllers diferentes, mas eles precisam ser inicializados antes, tanto usando o forma demonstrada no exemplo no início desse README, ou usando a classe `Bindings` 179 +## Gerenciamento de Dependência
724 180
725 -Concluindo, uma pessoa abriu um pedido para uma feature nova, como ele queria usar somente um tipo de variável reativa, e precisava inserir um Obx junto do GetBuilder para isso. Pensando nisso, `MixinBuilder` foi criado. Ele permite as duas formas de alterar estados: usando variáveis com `.obs`, ou a forma mecânica via `update()` 181 +**Veja uma explicação mais completa do gerenciamento de dependência [aqui](./docs/pt_BR/dependency_management.md)**
726 182
727 -Porém, desses 4 widgets, esse é o que consome mais recursos, já que usa os dois gerenciadores de estado combinados.  
728 -  
729 -- Nota: Para usar GetBuilder e MixinBuilder você precisa usar GetController. Para usar GetX ou Obx você precisa usar RxController.  
730 -  
731 -## Gerenciamento de dependências simples  
732 -* 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ê. 183 +- Nota: Se você está usando o gerenciador 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ê.
733 184
734 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: 185 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:
735 186
@@ -740,6 +191,7 @@ Controller controller = Get.put(Controller()); // Em vez de Controller controlle @@ -740,6 +191,7 @@ Controller controller = Get.put(Controller()); // Em vez de Controller controlle
740 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 191 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
741 192
742 Para que então você possa usar seu controller (ou uma classe Bloc) normalmente 193 Para que então você possa usar seu controller (ou uma classe Bloc) normalmente
  194 +
743 ```dart 195 ```dart
744 controller.fetchApi(); 196 controller.fetchApi();
745 ``` 197 ```
@@ -754,433 +206,28 @@ Controller controller = Get.find(); @@ -754,433 +206,28 @@ Controller controller = Get.find();
754 ``` 206 ```
755 207
756 E então você será capaz de recuperar os dados do seu controller que foram obtidos anteriormente: 208 E então você será capaz de recuperar os dados do seu controller que foram obtidos anteriormente:
  209 +
757 ```dart 210 ```dart
758 Text(controller.textFromApi); 211 Text(controller.textFromApi);
759 ``` 212 ```
  213 +
760 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 214 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
  215 +
761 ```dart 216 ```dart
762 Get.lazyPut<Service>(()=> ApiMock()); 217 Get.lazyPut<Service>(()=> ApiMock());
763 /// ApiMock só será chamado quando alguém usar o Get.find<Service> pela primeira vez 218 /// ApiMock só será chamado quando alguém usar o Get.find<Service> pela primeira vez
764 ``` 219 ```
765 220
766 -Se você quiser registar uma instância assíncrona, você pode usar `Get.putAsync()`:  
767 -  
768 -```dart  
769 -Get.putAsync<SharedPreferences>(() async {  
770 - final prefs = await SharedPreferences.getInstance();  
771 - await prefs.setInt('contador', 12345);  
772 - return prefs;  
773 -});  
774 -```  
775 -  
776 -Como usar:  
777 -```dart  
778 -int valor = Get.find<SharedPreferences>().getInt('contador');  
779 -print(valor); // Imprime: 123456  
780 -```  
781 -  
782 -Para remover a instância do Get:  
783 -```dart  
784 -Get.delete<Controller>();  
785 -```  
786 -  
787 -## Bindings  
788 -Um dos grandes diferenciais desse package, talvez, seja a possibilidade de integração total com rotas, gerenciador de estado e gerenciador de dependências.  
789 -  
790 -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.  
791 -  
792 -Na versão 2.10 Get implementou completamente a API Bindings.  
793 -  
794 -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.  
795 -  
796 -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.  
797 -  
798 -Isso permite Get saber qual tela está sendo mostrada quando um controller particular é usado e saber onde e como descartar o mesmo.  
799 -  
800 -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.  
801 -  
802 -### Como utilizar:  
803 -* Para usar essa API você só precisa criar uma classe que implementa a Bindings:  
804 -  
805 -```dart  
806 -class HomeBinding implements Bindings {}  
807 -```  
808 -  
809 -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:  
810 -  
811 -```dart  
812 -class HomeBinding implements Bindings{  
813 - @override  
814 - void dependencies() {  
815 - Get.lazyPut<ControllerX>(() => ControllerX());  
816 - Get.lazyPut<Service>(()=> Api());  
817 - }  
818 -}  
819 -```  
820 -  
821 -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.  
822 -  
823 -Usando rotas nomeadas  
824 -```dart  
825 -namedRoutes: {  
826 - '/': GetRoute(Home(), binding: HomeBinding())  
827 -}  
828 -```  
829 -  
830 -Usando rotas normais:  
831 -```dart  
832 -Get.to(Home(), binding: HomeBinding());  
833 -```  
834 -  
835 -Então, você não vai precisar se preocupar com gerenciamento da memória da sua aplicação mais, Get vai fazer para você.  
836 -  
837 -A classe Bindings é chamada quando uma rota é chamada. Você pode criar uma Binding inicial no seu GetMaterialApp para inserir todas as dependências que serão criadas.  
838 -  
839 -```dart  
840 -GetMaterialApp(  
841 - initialBinding: SampleBind(),  
842 - home: Home(),  
843 -)  
844 -```  
845 -  
846 -Se você quiser usar suas inicializações em um lugar, você pode usar `SmartManagement.keepfactory` para permitir isso.  
847 -  
848 -Sempre prefira usar SmartManagement padrão (full), você não precisa configurar nada pra isso, o Get já te entrega ele assim por padrão. Ele com certeza irá eliminar todos seus controladores em desuso da memória, pois seu controle refinado remove a dependência, ainda que haja uma falha e um widget que utiliza ele não seja disposado adequadamente. Ele também é seguro o bastante para ser usado só com StatelessWidget, pois possui inúmeros callbacks de segurança que impedirão de um controlador permanecer na memória se não estiver sendo usado por nenhum widget. No entanto, se você se incomodar com o comportamento padrão, ou simplesmente não quiser que isso ocorra, Get disponibiliza outras opções mais brandas de gerenciamento inteligente de memória, como o SmartManagement.onlyBuilders, que dependerá da remoção efetiva dos widgets que usam o controlador da árvore para removê-lo, e você poderá impedir que um controlador seja disposado usando "autoRemove:false" no seu GetBuilder/GetX.  
849 -  
850 -Com essa opção, apenas os controladores iniciados no "init:" ou carregados em um Binding com "Get.lazyPut" serão disposados, se você usar Get.put ou qualquer outra abordagem, o SmartManagement não terá permissões para excluir essa dependência.  
851 -  
852 -Com o comportamento padrão, até os widgets instanciados com "Get.put" serão removidos, sendo a diferença crucial entre eles.  
853 -  
854 -`SmartManagement.keepFactory` é como o SmartManagement.full, com uma única diferença. o full expurga até as fabricas das dependências, de forma que o Get.lazyPut() só conseguirá ser chamado uma única vez e sua fábrica e referências serão auto-destruídas. `SmartManagement.keepFactory` irá remover suas dependências quando necessário, no entanto, vai manter guardado a "forma" destas, para fabricar uma igual se você precisar novamente de uma instância daquela.  
855 -  
856 -Em vez de usar `SmartManagement.keepFactory` você pode usar Bindings. Bindings cria fábricas transitórias, que são criadas no momento que você clica para ir para outra tela, e será destruído assim que a animação de mudança de tela acontecer. É tão pouco tempo, que o analyzer sequer conseguirá registrá-lo. Quando você navegar para essa tela novamente, uma nova fábrica temporária será chamada, então isso é preferível à usar `SmartManagement.keepFactory`, mas se você não quer ter o trabalho de criar Bindings, ou deseja manter todas suas dependências no mesmo Binding, isso certamente irá te ajudar. Fábricas ocupam pouca memória, elas não guardam instâncias, mas uma função com a "forma" daquela classe que você quer. Isso é muito pouco, mas como o objetivo dessa lib é obter o máximo de desempenho possível usando o mínimo de recursos, Get remove até as fabricas por padrão. Use o que achar mais conveniente para você.  
857 -  
858 -- Nota: NÃO USE SmartManagement.keepfactory se você está usando vários Bindings. Ele foi criado para ser usado sem Bindings, ou com um único Binding ligado ao GetMaterialApp lá no `initialBinding`  
859 -  
860 -- Nota²: Usar Bindings é completamente opcional, você pode usar Get.put() e Get.find() em classes que usam o controller sem problemas. Porém, se você trabalhar com Services ou qualquer outra abstração, eu recomendo usar Bindings. Especialmente em grandes empresas.  
861 -  
862 -## Workers  
863 -Workers vai te dar suporte, ativando callbacks específicos quando um evento ocorrer.  
864 -  
865 -```dart  
866 -/// Chamada toda vez que a variável for alterada  
867 -ever(count1, (value) => print("novo valor: $value"));  
868 -  
869 -/// Chamada apenas na primeira vez que a variável for alterada  
870 -once(count1, (value) => print("novo valor: $value (não vai mudar mais)"));  
871 -  
872 -/// Anti DDos - Chamada toda vez que o usuário parar de digitar por 1 segundo, por exemplo.  
873 -debounce(count1, (value) => print("debouce $value"), time: Duration(seconds: 1));  
874 -  
875 -/// Ignore todas as mudanças num período de 1 segundo.  
876 -interval(count1, (value) => print("interval $value"), time: Duration(seconds: 1));  
877 -```  
878 -- **ever**  
879 -é chamado toda vez que a variável mudar de valor. É só isso.  
880 -  
881 -- **once**  
882 -é chamado somente na primeira vez que a variável mudar de valor.  
883 -  
884 -- **debounce**  
885 -É 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.  
886 -  
887 -- **interval**  
888 -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.  
889 -  
890 -## Navegar com rotas nomeadas  
891 -- Se você prefere navegar por rotas nomeadas, Get também dá suporte a isso:  
892 -  
893 -Para navegar para uma nova tela  
894 -```dart  
895 -Get.toNamed("/ProximaTela");  
896 -```  
897 -  
898 -Para navegar para uma tela sem a opção de voltar para a rota atual.  
899 -```dart  
900 -Get.offNamed("/ProximaTela");  
901 -```  
902 -  
903 -Para navegar para uma nova tela e remover todas rotas anteriores da stack  
904 -```dart  
905 -Get.offAllNamed("/ProximaTela");  
906 -```  
907 -  
908 -Para definir rotas, use o `GetMaterialApp`:  
909 -```dart  
910 -void main() {  
911 - runApp(  
912 - GetMaterialApp(  
913 - initialRoute: '/',  
914 - namedRoutes: {  
915 - '/': GetRoute(page: MyHomePage()),  
916 - '/login': GetRoute(page: Login()),  
917 - '/cadastro': GetRoute(page: Cadastro(),transition: Transition.cupertino);  
918 - },  
919 - )  
920 - );  
921 -}  
922 -```  
923 -  
924 -### Enviar dados para rotas nomeadas  
925 -  
926 -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.  
927 -```dart  
928 -Get.toNamed("/ProximaTela", arguments: 'Get é o melhor');  
929 -```  
930 -  
931 -Na sua classe ou controller:  
932 -```dart  
933 -print(Get.arguments); //valor: Get é o melhor  
934 -```  
935 -#### Links de Url dinâmicos  
936 -  
937 -Get oferece links de url dinâmicos assim como na Web.  
938 -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.  
939 -```dart  
940 -Get.offAllNamed("/ProximaTela?device=phone&id=354&name=Enzo");  
941 -```  
942 -na sua classe controller/bloc/stateful/stateless:  
943 -```dart  
944 -print(Get.parameters['id']); // valor: 354  
945 -print(Get.parameters['name']); // valor: Enzo  
946 -```  
947 -  
948 -Você também pode receber parâmetros nomeados com o Get facilmente:  
949 -```dart  
950 -void main() => runApp(  
951 - GetMaterialApp(  
952 - initialRoute: '/',  
953 - namedRoutes: {  
954 - '/': GetRoute(page: MyHomePage()),  
955 - /// Importante! ':user' não é uma nova rota, é somente uma  
956 - /// especificação do parâmentro. Não use '/segunda/:user/' e '/segunda'  
957 - /// se você precisa de uma nova rota para o user, então  
958 - /// use '/segunda/user/:user' se '/segunda' for uma rota  
959 - '/segunda/:user': GetRoute(page: Segunda()), // recebe a ID  
960 - '/terceira': GetRoute(page: Terceira(),transition: Transition.cupertino);  
961 - },  
962 - ),  
963 -);  
964 -```  
965 -Envie dados na rota nomeada  
966 -```dart  
967 -Get.toNamed("/segunda/34954");  
968 -```  
969 -  
970 -Na segunda tela receba os dados usando `Get.parameters[]`  
971 -```dart  
972 -print(Get.parameters['user']); // valor: 34954  
973 -```  
974 -  
975 -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 ❤  
976 -  
977 -  
978 -#### Middleware 221 +### Explicação completa
979 222
980 -Se você quer escutar eventos do Get para ativar ações, você pode usar `routingCallback` para isso  
981 -```dart  
982 -GetMaterialApp(  
983 - routingCallback: (route){  
984 - if(routing.current == '/segunda'){  
985 - openAds();  
986 - }  
987 - }  
988 -)  
989 -``` 223 +**Veja uma explicação mais completa do gerenciamento de dependência [aqui](./docs/pt_BR/dependency_management.md)**
990 224
991 -Se você não estiver usando o `GetMaterialApp`, você pode usar a API manual para anexar um observer Middleware.  
992 -```dart  
993 -void main() {  
994 - runApp(  
995 - MaterialApp(  
996 - onGenerateRoute: Router.generateRoute,  
997 - initialRoute: "/",  
998 - navigatorKey: Get.key,  
999 - navigatorObservers: [  
1000 - GetObserver(MiddleWare.observer), // AQUI !!!  
1001 - ],  
1002 - )  
1003 - );  
1004 -}  
1005 -```  
1006 -  
1007 -Criar uma classe MiddleWare  
1008 -```dart  
1009 -class MiddleWare {  
1010 - static observer(Routing routing) {  
1011 - /// Você pode escutar junto com as rotas, snackbars, dialogs  
1012 - /// e bottomsheets em cada tela.  
1013 - /// Se você precisar entrar em algum um desses 3 eventos aqui diretamente,  
1014 - /// você precisa especificar que o evento é != do que você está tentando fazer  
1015 - if (routing.current == '/segunda' && !routing.isSnackbar) {  
1016 - Get.snackbar("Olá", "Você está na segunda rota");  
1017 - } else if (routing.current =='/terceira'){  
1018 - print('última rota chamada');  
1019 - }  
1020 - }  
1021 -}  
1022 -```  
1023 -  
1024 -Agora, use Get no seu código:  
1025 -```dart  
1026 -class Primeira extends StatelessWidget {  
1027 - @override  
1028 - Widget build(BuildContext context) {  
1029 - return Scaffold(  
1030 - appBar: AppBar(  
1031 - leading: IconButton(  
1032 - icon: Icon(Icons.add),  
1033 - onPressed: () {  
1034 - Get.snackbar("Oi", "eu sou uma snackbar moderna");  
1035 - },  
1036 - ),  
1037 - title: Text('Primeira rota'),  
1038 - ),  
1039 - body: Center(  
1040 - child: RaisedButton(  
1041 - child: Text('Abrir rota'),  
1042 - onPressed: () {  
1043 - Get.toNamed("/segunda");  
1044 - },  
1045 - ),  
1046 - ),  
1047 - );  
1048 - }  
1049 -}  
1050 -  
1051 -class Segunda extends StatelessWidget {  
1052 - @override  
1053 - Widget build(BuildContext context) {  
1054 - return Scaffold(  
1055 - appBar: AppBar(  
1056 - leading: IconButton(  
1057 - icon: Icon(Icons.add),  
1058 - onPressed: () {  
1059 - Get.snackbar("Oi", "eu sou uma snackbar moderna");  
1060 - },  
1061 - ),  
1062 - title: Text('Segunda rota'),  
1063 - ),  
1064 - body: Center(  
1065 - child: RaisedButton(  
1066 - child: Text('Abrir rota'),  
1067 - onPressed: () {  
1068 - Get.toNamed("/terceira");  
1069 - },  
1070 - ),  
1071 - ),  
1072 - );  
1073 - }  
1074 -}  
1075 -  
1076 -class Terceira extends StatelessWidget {  
1077 - @override  
1078 - Widget build(BuildContext context) {  
1079 - return Scaffold(  
1080 - appBar: AppBar(  
1081 - title: Text("Terceira Rota"),  
1082 - ),  
1083 - body: Center(  
1084 - child: RaisedButton(  
1085 - onPressed: () {  
1086 - Get.back();  
1087 - },  
1088 - child: Text('Voltar!'),  
1089 - ),  
1090 - ),  
1091 - );  
1092 - }  
1093 -}  
1094 -``` 225 +# Utilidades
1095 226
1096 -### Change Theme  
1097 -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.  
1098 -  
1099 -Você pode criar seu tema customizado e simplesmente adicionar ele dentro de `Get.changeTheme()` sem nenhum boilerplate para isso:  
1100 -```dart  
1101 -Get.changeTheme(ThemeData.light());  
1102 -```  
1103 -  
1104 -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:  
1105 -```dart  
1106 -Get.changeTheme(Get.isDarkMode? ThemeData.light(): ThemeData.dark());  
1107 -```  
1108 -Quando o modo escuro está ativado, ele vai alterar para o modo claro, e vice versa.  
1109 -  
1110 -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:  
1111 -- [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).  
1112 -  
1113 -### Configurações Globais Opcionais  
1114 -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  
1115 -```dart  
1116 -// essa forma  
1117 -GetMaterialApp(  
1118 - enableLog: true,  
1119 - defaultTransition: Transition.fade,  
1120 - opaqueRoute: Get.isOpaqueRouteDefault,  
1121 - popGesture: Get.isPopGestureEnable,  
1122 - transitionDuration: Get.defaultDurationTransition,  
1123 - defaultGlobalState: Get.defaultGlobalState,  
1124 -);  
1125 -  
1126 -// ou essa  
1127 -Get.config(  
1128 - enableLog = true,  
1129 - defaultPopGesture = true,  
1130 - defaultTransition = Transitions.cupertino  
1131 -)  
1132 -  
1133 -### Nested Navigators  
1134 -  
1135 -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.  
1136 -  
1137 -* 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.  
1138 -  
1139 -Veja como é simples:  
1140 -```dart  
1141 -Navigator(  
1142 - key: nestedKey(1), // crie uma key com um index  
1143 - initialRoute: '/',  
1144 - onGenerateRoute: (settings) {  
1145 - if (settings.name == '/') {  
1146 - return GetRouteBase(  
1147 - page: Scaffold(  
1148 - appBar: AppBar(  
1149 - title: Text("Principal"),  
1150 - ),  
1151 - body: Center(  
1152 - child: FlatButton(  
1153 - color: Colors.blue,  
1154 - child: Text("Ir para a segunda"),  
1155 - onPressed: () {  
1156 - Get.toNamed('/segunda', id:1); // navega pela sua navegação aninhada usando o index  
1157 - },  
1158 - )  
1159 - ),  
1160 - ),  
1161 - );  
1162 - } else if (settings.name == '/segunda') {  
1163 - return GetRouteBase(  
1164 - page: Center(  
1165 - child: Scaffold(  
1166 - appBar: AppBar(  
1167 - title: Text("Principal"),  
1168 - ),  
1169 - body: Center(  
1170 - child: Text("Segunda")  
1171 - ),  
1172 - ),  
1173 - ),  
1174 - );  
1175 - }  
1176 - }  
1177 -),  
1178 -```  
1179 -  
1180 -```  
1181 -### Outras APIs avançadas e Configurações Manuais 227 +## Outras APIs avançadas e Configurações Manuais
1182 228
1183 GetMaterialApp configura tudo para você, mas se quiser configurar Get manualmente, você pode usando APIs avançadas. 229 GetMaterialApp configura tudo para você, mas se quiser configurar Get manualmente, você pode usando APIs avançadas.
  230 +
1184 ```dart 231 ```dart
1185 MaterialApp( 232 MaterialApp(
1186 navigatorKey: Get.key, 233 navigatorKey: Get.key,
@@ -1189,6 +236,7 @@ MaterialApp( @@ -1189,6 +236,7 @@ MaterialApp(
1189 ``` 236 ```
1190 237
1191 Você também será capaz de usar seu próprio Middleware dentro do GetObserver, isso não irá influenciar em nada. 238 Você também será capaz de usar seu próprio Middleware dentro do GetObserver, isso não irá influenciar em nada.
  239 +
1192 ```dart 240 ```dart
1193 MaterialApp( 241 MaterialApp(
1194 navigatorKey: Get.key, 242 navigatorKey: Get.key,
@@ -1198,7 +246,7 @@ MaterialApp( @@ -1198,7 +246,7 @@ MaterialApp(
1198 246
1199 ```dart 247 ```dart
1200 // fornece os arguments da tela atual 248 // fornece os arguments da tela atual
1201 -Get.arguments 249 +Get.arguments
1202 250
1203 // fornece os arguments da rota anterior 251 // fornece os arguments da rota anterior
1204 Get.previousArguments 252 Get.previousArguments
@@ -1233,12 +281,12 @@ Get.offUntil() @@ -1233,12 +281,12 @@ Get.offUntil()
1233 281
1234 // vá para a próxima rota nomeada e remove todas as 282 // vá para a próxima rota nomeada e remove todas as
1235 //rotas anteriores até que o predicate retorne true. 283 //rotas anteriores até que o predicate retorne true.
1236 -Get.offNamedUntil() 284 +Get.offNamedUntil()
1237 285
1238 // retorna qual é a plataforma 286 // retorna qual é a plataforma
1239 //(Esse método é completamente compatível com o FlutterWeb, 287 //(Esse método é completamente compatível com o FlutterWeb,
1240 //diferente do método do framework "Platform.isAndroid") 288 //diferente do método do framework "Platform.isAndroid")
1241 -GetPlatform.isAndroid/isIOS/isWeb... 289 +GetPlatform.isAndroid/isIOS/isWeb...
1242 290
1243 // Equivalente ao método: MediaQuery.of(context).size.height, mas é imutável. 291 // Equivalente ao método: MediaQuery.of(context).size.height, mas é imutável.
1244 // Se você precisa de um height adaptável (como em navegadores em que a janela pode ser redimensionada) 292 // Se você precisa de um height adaptável (como em navegadores em que a janela pode ser redimensionada)
@@ -1259,5 +307,3 @@ Get.contextOverlay @@ -1259,5 +307,3 @@ Get.contextOverlay
1259 ``` 307 ```
1260 308
1261 Essa biblioteca sempre será atualizada e terá sempre nova features sendo implementadas. Sinta-se livre para oferecer PRs e contribuir com o package. 309 Essa biblioteca sempre será atualizada e terá sempre nova features sendo implementadas. Sinta-se livre para oferecer PRs e contribuir com o package.
1262 -  
1263 -  
  1 +
  2 +# Dependency Management
  3 +
  4 +## Simple Instance Manager
  5 +
  6 +- Note: If you are using Get's State Manager, you don't have to worry about that, just read for information, but pay more attention to the bindings api, which will do all of this automatically for you.
  7 +
  8 +Are you already using Get and want to make your project as lean as possible? Get has a simple and powerful dependency manager that allows you to retrieve the same class as your Bloc or Controller with just 1 lines of code, no Provider context, no inheritedWidget:
  9 +
  10 +```dart
  11 +Controller controller = Get.put(Controller()); // Rather Controller controller = Controller();
  12 +```
  13 +
  14 +Instead of instantiating your class within the class you are using, you are instantiating it within the Get instance, which will make it available throughout your App.
  15 +So you can use your controller (or class Bloc) normally
  16 +
  17 +```dart
  18 +controller.fetchApi();
  19 +```
  20 +
  21 +Imagine that you have navigated through numerous routes, and you need a data that was left behind in your controller, you would need a state manager combined with the Provider or Get_it, correct? Not with Get. You just need to ask Get to "find" for your controller, you don't need any additional dependencies:
  22 +
  23 +```dart
  24 +Controller controller = Get.find();
  25 +//Yes, it looks like Magic, Get will find your controller, and will deliver it to you. You can have 1 million controllers instantiated, Get will always give you the right controller.
  26 +```
  27 +
  28 +And then you will be able to recover your controller data that was obtained back there:
  29 +
  30 +```dart
  31 +Text(controller.textFromApi);
  32 +```
  33 +
  34 +Looking for lazy loading? You can declare all your controllers, and it will be called only when someone needs it. You can do this with:
  35 +
  36 +```dart
  37 +Get.lazyPut<Service>(()=> ApiMock());
  38 +/// ApiMock will only be called when someone uses Get.find<Service> for the first time
  39 +```
  40 +
  41 +If you want to register an asynchronous instance, you can use Get.putAsync.
  42 +
  43 +```dart
  44 +Get.putAsync<SharedPreferences>(() async {
  45 + final prefs = await SharedPreferences.getInstance();
  46 + await prefs.setInt('counter', 12345);
  47 + return prefs;
  48 +});
  49 +```
  50 +
  51 +usage:
  52 +
  53 +```dart
  54 +int count = Get.find<SharedPreferences>().getInt('counter');
  55 +print(count); // out: 12345
  56 +```
  57 +
  58 +To remove a instance of Get:
  59 +
  60 +```dart
  61 +Get.delete<Controller>();
  62 +```
  63 +
  64 +## Bindings
  65 +
  66 +One of the great differentials of this package, perhaps, is the possibility of full integration of the routes, state manager and dependency manager.
  67 +When a route is removed from the Stack, all controllers, variables, and instances of objects related to it are removed from memory. If you are using streams or timers, they will be closed automatically, and you don't have to worry about any of that.
  68 +In version 2.10 Get completely implemented the Bindings API.
  69 +Now you no longer need to use the init method. You don't even have to type your controllers if you don't want to. You can start your controllers and services in the appropriate place for that.
  70 +The Binding class is a class that will decouple dependency injection, while "binding" routes to the state manager and dependency manager.
  71 +This allows Get to know which screen is being displayed when a particular controller is used and to know where and how to dispose of it.
  72 +In addition, the Binding class will allow you to have SmartManager configuration control. You can configure the dependencies to be arranged when removing a route from the stack, or when the widget that used it is laid out, or neither. You will have intelligent dependency management working for you, but even so, you can configure it as you wish.
  73 +
  74 +### How to use
  75 +
  76 +- Create a class and implements Binding
  77 +
  78 +```dart
  79 +class HomeBinding implements Bindings{
  80 +```
  81 +
  82 +Your IDE will automatically ask you to override the "dependencies" method, and you just need to click on the lamp, override the method, and insert all the classes you are going to use on that route:
  83 +
  84 +```dart
  85 +class HomeBinding implements Bindings{
  86 + @override
  87 + void dependencies() {
  88 + Get.lazyPut<ControllerX>(() => ControllerX());
  89 + Get.lazyPut<Service>(()=> Api());
  90 + }
  91 +}
  92 +```
  93 +
  94 +Now you just need to inform your route, that you will use that binding to make the connection between route manager, dependencies and states.
  95 +
  96 +- Using named routes:
  97 +
  98 +```dart
  99 +namedRoutes: {
  100 + '/': GetRoute(Home(), binding: HomeBinding())
  101 +}
  102 +```
  103 +
  104 +- Using normal routes:
  105 +
  106 +```dart
  107 +Get.to(Home(), binding: HomeBinding());
  108 +```
  109 +
  110 +There, you don't have to worry about memory management of your application anymore, Get will do it for you.
  111 +
  112 +The Binding class is called when a route is called, you can create an "initialBinding in your GetMaterialApp to insert all the dependencies that will be created.
  113 +
  114 +```dart
  115 +GetMaterialApp(
  116 + initialBinding: SampleBind(),
  117 + home: Home(),
  118 +);
  119 +```
  120 +
  121 +## SmartManagement
  122 +
  123 +Always prefer to use standard SmartManagement (full), you do not need to configure anything for that, Get already gives it to you by default. It will surely eliminate all your disused controllers from memory, as its refined control removes the dependency, even if a failure occurs and a widget that uses it is not properly disposed.
  124 +The "full" mode is also safe enough to be used with StatelessWidget, as it has numerous security callbacks that will prevent a controller from remaining in memory if it is not being used by any widget, and disposition is not important here. However, if you are bothered by the default behavior, or just don't want it to happen, Get offers other, more lenient options for intelligent memory management, such as SmartManagement.onlyBuilders, which will depend on the effective removal of widgets using the controller. tree to remove it, and you can prevent a controller from being deployed using "autoRemove: false" in your GetBuilder/GetX.
  125 +With this option, only controllers started in "init:" or loaded into a Binding with "Get.lazyPut" will be disposed, if you use Get.put or any other approach, SmartManagement will not have permissions to exclude this dependency.
  126 +With the default behavior, even widgets instantiated with "Get.put" will be removed, unlike SmartManagement.onlyBuilders.
  127 +SmartManagement.keepFactory is like SmartManagement.full, with one difference. SmartManagement.full purges the factories from the premises, so that Get.lazyPut() will only be able to be called once and your factory and references will be self-destructing. SmartManagement.keepFactory will remove its dependencies when necessary, however, it will keep the "shape" of these, to make an equal one if you need an instance of that again.
  128 +Instead of using SmartManagement.keepFactory you can use Bindings.
  129 +Bindings creates transitory factories, which are created the moment you click to go to another screen, and will be destroyed as soon as the screen-changing animation happens. It is so little time that the analyzer will not even be able to register it. When you navigate to this screen again, a new temporary factory will be called, so this is preferable to using SmartManagement.keepFactory, but if you don't want to create Bindings, or want to keep all your dependencies on the same Binding, it will certainly help you . Factories take up little memory, they don't hold instances, but a function with the "shape" of that class you want. This is very little, but since the purpose of this lib is to get the maximum performance possible using the minimum resources, Get removes even the factories by default. Use whichever is most convenient for you.
  130 +
  131 +- NOTE: DO NOT USE SmartManagement.keepFactory if you are using multiple Bindings. It was designed to be used without Bindings, or with a single Binding linked in the GetMaterialApp's initialBinding.
  132 +
  133 +- NOTE2: Using Bindings is completely optional, you can use Get.put() and Get.find() on classes that use a given controller without any problem.
  134 +However, if you work with Services or any other abstraction, I recommend using Bindings for a larger organization.
  1 +
  2 +# Route Management
  3 +
  4 +## How to use
  5 +
  6 +Add this to your pubspec.yaml file:
  7 +
  8 +```yaml
  9 +dependencies:
  10 + get:
  11 +```
  12 +
  13 +If you are going to use routes/snackbars/dialogs/bottomsheets without context, or use the high-level Get APIs, you need to simply add "Get" before your MaterialApp, turning it into GetMaterialApp and enjoy!
  14 +
  15 +```dart
  16 +GetMaterialApp( // Before: MaterialApp(
  17 + home: MyHome(),
  18 +)
  19 +```
  20 +
  21 +## Navigation without named routes
  22 +
  23 +To navigate to a new screen:
  24 +
  25 +```dart
  26 +Get.to(NextScreen());
  27 +```
  28 +
  29 +To close snackbars, dialogs, bottomsheets, or anything you would normally close with Navigator.pop(context);
  30 +
  31 +```dart
  32 +Get.back();
  33 +```
  34 +
  35 +To go to the next screen and no option to go back to the previous screen (for use in SplashScreens, login screens and etc.)
  36 +
  37 +```dart
  38 +Get.off(NextScreen());
  39 +```
  40 +
  41 +To go to the next screen and cancel all previous routes (useful in shopping carts, polls, and tests)
  42 +
  43 +```dart
  44 +Get.offAll(NextScreen());
  45 +```
  46 +
  47 +To navigate to the next route, and receive or update data as soon as you return from it:
  48 +
  49 +```dart
  50 +var data = await Get.to(Payment());
  51 +```
  52 +
  53 +on other screen, send a data for previous route:
  54 +
  55 +```dart
  56 +Get.back(result: 'success');
  57 +```
  58 +
  59 +And use it:
  60 +
  61 +ex:
  62 +
  63 +```dart
  64 +if(data == 'success') madeAnything();
  65 +```
  66 +
  67 +Don't you want to learn our syntax?
  68 +Just change the Navigator (uppercase) to navigator (lowercase), and you will have all the functions of the standard navigation, without having to use context
  69 +Example:
  70 +
  71 +```dart
  72 +
  73 +// Default Flutter navigator
  74 +Navigator.of(context).push(
  75 + context,
  76 + MaterialPageRoute(
  77 + builder: (BuildContext context) {
  78 + return HomePage();
  79 + },
  80 + ),
  81 +);
  82 +
  83 +// Get using Flutter syntax without needing context
  84 +navigator.push(
  85 + MaterialPageRoute(
  86 + builder: (_) {
  87 + return HomePage();
  88 + },
  89 + ),
  90 +);
  91 +
  92 +// Get syntax (It is much better, but you have the right to disagree)
  93 +Get.to(HomePage());
  94 +
  95 +
  96 +```
  97 +
  98 +## Navigation with named routes
  99 +
  100 +- If you prefer to navigate by namedRoutes, Get also supports this.
  101 +
  102 +To navigate to nextScreen
  103 +
  104 +```dart
  105 +Get.toNamed("/NextScreen");
  106 +```
  107 +
  108 +To navigate and remove the previous screen from the tree.
  109 +
  110 +```dart
  111 +Get.offNamed("/NextScreen");
  112 +```
  113 +
  114 +To navigate and remove all previous screens from the tree.
  115 +
  116 +```dart
  117 +Get.offAllNamed("/NextScreen");
  118 +```
  119 +
  120 +To define routes, use GetMaterialApp:
  121 +
  122 +```dart
  123 +void main() {
  124 + runApp(
  125 + GetMaterialApp(
  126 + initialRoute: '/',
  127 + getPages: [
  128 + GetPage(name: '/', page: () => MyHomePage()),
  129 + GetPage(name: '/second', page: () => Second()),
  130 + GetPage(
  131 + name: '/third',
  132 + page: () => Third(),
  133 + transition: Transition.zoom
  134 + ),
  135 + ],
  136 + )
  137 + );
  138 +}
  139 +```
  140 +
  141 +### Send data to named Routes
  142 +
  143 +Just send what you want for arguments. Get accepts anything here, whether it is a String, a Map, a List, or even a class instance.
  144 +
  145 +```dart
  146 +Get.toNamed("/NextScreen", arguments: 'Get is the best');
  147 +```
  148 +
  149 +on your class or controller:
  150 +
  151 +```dart
  152 +print(Get.arguments);
  153 +//print out: Get is the best
  154 +```
  155 +
  156 +### Dynamic urls links
  157 +
  158 +Get offer advanced dynamic urls just like on the Web. Web developers have probably already wanted this feature on Flutter, and most likely have seen a package promise this feature and deliver a totally different syntax than a URL would have on web, but Get also solves that.
  159 +
  160 +```dart
  161 +Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo");
  162 +```
  163 +
  164 +on your controller/bloc/stateful/stateless class:
  165 +
  166 +```dart
  167 +print(Get.parameters['id']);
  168 +// out: 354
  169 +print(Get.parameters['name']);
  170 +// out: Enzo
  171 +```
  172 +
  173 +You can also receive NamedParameters with Get easily:
  174 +
  175 +```dart
  176 +void main() {
  177 + runApp(
  178 + GetMaterialApp(
  179 + initialRoute: '/',
  180 + getPages: [
  181 + GetPage(
  182 + name: '/',
  183 + page: () => MyHomePage(),
  184 + ),
  185 + GetPage(
  186 + name: '/profile/',
  187 + page: () => MyProfile(),
  188 + ),
  189 + //You can define a different page for routes with arguments, and another without arguments, but for that you must use the slash '/' on the route that will not receive arguments as above.
  190 + GetPage(
  191 + name: '/profile/:user',
  192 + page: () => UserProfile(),
  193 + ),
  194 + GetPage(
  195 + name: '/third',
  196 + page: () => Third(),
  197 + transition: Transition.cupertino
  198 + ),
  199 + ],
  200 + )
  201 + );
  202 +}
  203 +```
  204 +
  205 +Send data on route name
  206 +
  207 +```dart
  208 +Get.toNamed("/second/34954");
  209 +```
  210 +
  211 +On second screen take the data by parameter
  212 +
  213 +```dart
  214 +print(Get.parameters['user']);
  215 +// out: 34954
  216 +```
  217 +
  218 +And now, all you need to do is use Get.toNamed() to navigate your named routes, without any context (you can call your routes directly from your BLoC or Controller class), and when your app is compiled to the web, your routes will appear in the url <3
  219 +
  220 +### Middleware
  221 +
  222 +If you want listen Get events to trigger actions, you can to use routingCallback to it
  223 +
  224 +```dart
  225 +GetMaterialApp(
  226 + routingCallback: (routing) {
  227 + if(routing.current == '/second'){
  228 + openAds();
  229 + }
  230 + }
  231 +)
  232 +```
  233 +
  234 +If you are not using GetMaterialApp, you can use the manual API to attach Middleware observer.
  235 +
  236 +```dart
  237 +void main() {
  238 + runApp(
  239 + MaterialApp(
  240 + onGenerateRoute: Router.generateRoute,
  241 + initialRoute: "/",
  242 + navigatorKey: Get.key,
  243 + navigatorObservers: [
  244 + GetObserver(MiddleWare.observer), // HERE !!!
  245 + ],
  246 + ),
  247 + );
  248 +}
  249 +```
  250 +
  251 +Create a MiddleWare class
  252 +
  253 +```dart
  254 +class MiddleWare {
  255 + static observer(Routing routing) {
  256 + /// You can listen in addition to the routes, the snackbars, dialogs and bottomsheets on each screen.
  257 + ///If you need to enter any of these 3 events directly here,
  258 + ///you must specify that the event is != Than you are trying to do.
  259 + if (routing.current == '/second' && !routing.isSnackbar) {
  260 + Get.snackbar("Hi", "You are on second route");
  261 + } else if (routing.current =='/third'){
  262 + print('last route called');
  263 + }
  264 + }
  265 +}
  266 +```
  267 +
  268 +Now, use Get on your code:
  269 +
  270 +```dart
  271 +class First extends StatelessWidget {
  272 + @override
  273 + Widget build(BuildContext context) {
  274 + return Scaffold(
  275 + appBar: AppBar(
  276 + leading: IconButton(
  277 + icon: Icon(Icons.add),
  278 + onPressed: () {
  279 + Get.snackbar("hi", "i am a modern snackbar");
  280 + },
  281 + ),
  282 + title: Text('First Route'),
  283 + ),
  284 + body: Center(
  285 + child: RaisedButton(
  286 + child: Text('Open route'),
  287 + onPressed: () {
  288 + Get.toNamed("/second");
  289 + },
  290 + ),
  291 + ),
  292 + );
  293 + }
  294 +}
  295 +
  296 +class Second extends StatelessWidget {
  297 + @override
  298 + Widget build(BuildContext context) {
  299 + return Scaffold(
  300 + appBar: AppBar(
  301 + leading: IconButton(
  302 + icon: Icon(Icons.add),
  303 + onPressed: () {
  304 + Get.snackbar("hi", "i am a modern snackbar");
  305 + },
  306 + ),
  307 + title: Text('second Route'),
  308 + ),
  309 + body: Center(
  310 + child: RaisedButton(
  311 + child: Text('Open route'),
  312 + onPressed: () {
  313 + Get.toNamed("/third");
  314 + },
  315 + ),
  316 + ),
  317 + );
  318 + }
  319 +}
  320 +
  321 +class Third extends StatelessWidget {
  322 + @override
  323 + Widget build(BuildContext context) {
  324 + return Scaffold(
  325 + appBar: AppBar(
  326 + title: Text("Third Route"),
  327 + ),
  328 + body: Center(
  329 + child: RaisedButton(
  330 + onPressed: () {
  331 + Get.back();
  332 + },
  333 + child: Text('Go back!'),
  334 + ),
  335 + ),
  336 + );
  337 + }
  338 +}
  339 +```
  340 +
  341 +## Navigation without context
  342 +
  343 +### SnackBars
  344 +
  345 +To have a simple SnackBar with Flutter, you must get the context of Scaffold, or you must use a GlobalKey attached to your Scaffold
  346 +
  347 +```dart
  348 +final snackBar = SnackBar(
  349 + content: Text('Hi!'),
  350 + action: SnackBarAction(
  351 + label: 'I am a old and ugly snackbar :(',
  352 + onPressed: (){}
  353 + ),
  354 +);
  355 +// Find the Scaffold in the widget tree and use
  356 +// it to show a SnackBar.
  357 +Scaffold.of(context).showSnackBar(snackBar);
  358 +```
  359 +
  360 +With Get:
  361 +
  362 +```dart
  363 +Get.snackbar('Hi', 'i am a modern snackbar');
  364 +```
  365 +
  366 +With Get, all you have to do is call your Get.snackbar from anywhere in your code or customize it however you want!
  367 +
  368 +```dart
  369 +Get.snackbar(
  370 + "Hey i'm a Get SnackBar!", // title
  371 + "It's unbelievable! I'm using SnackBar without context, without boilerplate, without Scaffold, it is something truly amazing!", // message
  372 + icon: Icon(Icons.alarm),
  373 + shouldIconPulse: true,
  374 + onTap:(){},
  375 + barBlur: 20,
  376 + isDismissible: true,
  377 + duration: Duration(seconds: 3),
  378 +);
  379 +
  380 +
  381 + ////////// ALL FEATURES //////////
  382 + // Color colorText,
  383 + // Duration duration,
  384 + // SnackPosition snackPosition,
  385 + // Widget titleText,
  386 + // Widget messageText,
  387 + // bool instantInit,
  388 + // Widget icon,
  389 + // bool shouldIconPulse,
  390 + // double maxWidth,
  391 + // EdgeInsets margin,
  392 + // EdgeInsets padding,
  393 + // double borderRadius,
  394 + // Color borderColor,
  395 + // double borderWidth,
  396 + // Color backgroundColor,
  397 + // Color leftBarIndicatorColor,
  398 + // List<BoxShadow> boxShadows,
  399 + // Gradient backgroundGradient,
  400 + // FlatButton mainButton,
  401 + // OnTap onTap,
  402 + // bool isDismissible,
  403 + // bool showProgressIndicator,
  404 + // AnimationController progressIndicatorController,
  405 + // Color progressIndicatorBackgroundColor,
  406 + // Animation<Color> progressIndicatorValueColor,
  407 + // SnackStyle snackStyle,
  408 + // Curve forwardAnimationCurve,
  409 + // Curve reverseAnimationCurve,
  410 + // Duration animationDuration,
  411 + // double barBlur,
  412 + // double overlayBlur,
  413 + // Color overlayColor,
  414 + // Form userInputForm
  415 + ///////////////////////////////////
  416 +```
  417 +
  418 +If you prefer the traditional snackbar, or want to customize it from scratch, including adding just one line (Get.snackbar makes use of a mandatory title and message), you can use
  419 +`Get.rawSnackbar();` which provides the RAW API on which Get.snackbar was built.
  420 +
  421 +### Dialogs
  422 +
  423 +To open dialog:
  424 +
  425 +```dart
  426 +Get.dialog(YourDialogWidget());
  427 +```
  428 +
  429 +To open default dialog:
  430 +
  431 +```dart
  432 +Get.defaultDialog(
  433 + onConfirm: () => print("Ok"),
  434 + middleText: "Dialog made in 3 lines of code"
  435 +);
  436 +```
  437 +
  438 +You can also use Get.generalDialog instead of showGeneralDialog.
  439 +
  440 +For all other Flutter dialog widgets, including cupertinos, you can use Get.overlayContext instead of context, and open it anywhere in your code.
  441 +For widgets that don't use Overlay, you can use Get.context.
  442 +These two contexts will work in 99% of cases to replace the context of your UI, except for cases where inheritedWidget is used without a navigation context.
  443 +
  444 +### BottomSheets
  445 +
  446 +Get.bottomSheet is like showModalBottomSheet, but don't need of context.
  447 +
  448 +```dart
  449 +Get.bottomSheet(
  450 + Container(
  451 + child: Wrap(
  452 + children: <Widget>[
  453 + ListTile(
  454 + leading: Icon(Icons.music_note),
  455 + title: Text('Music'),
  456 + onTap: () => {}
  457 + ),
  458 + ListTile(
  459 + leading: Icon(Icons.videocam),
  460 + title: Text('Video'),
  461 + onTap: () => {},
  462 + ),
  463 + ],
  464 + ),
  465 + );
  466 +);
  467 +```
  468 +
  469 +## Nested Navigation
  470 +
  471 +Get made Flutter's nested navigation even easier.
  472 +You don't need the context, and you will find your navigation stack by Id.
  473 +
  474 +- NOTE: Creating parallel navigation stacks can be dangerous. The ideal is not to use NestedNavigators, or to use sparingly. If your project requires it, go ahead, but keep in mind that keeping multiple navigation stacks in memory may not be a good idea for RAM consumption.
  475 +
  476 +See how simple it is:
  477 +
  478 +```dart
  479 +Navigator(
  480 + key: Get.nestedKey(1), // create a key by index
  481 + initialRoute: '/',
  482 + onGenerateRoute: (settings) {
  483 + if (settings.name == '/') {
  484 + return GetPageRoute(
  485 + page: Scaffold(
  486 + appBar: AppBar(
  487 + title: Text("Main"),
  488 + ),
  489 + body: Center(
  490 + child: FlatButton(
  491 + color: Colors.blue,
  492 + onPressed: () {
  493 + Get.toNamed('/second', id:1); // navigate by your nested route by index
  494 + },
  495 + child: Text("Go to second"),
  496 + ),
  497 + ),
  498 + ),
  499 + );
  500 + } else if (settings.name == '/second') {
  501 + return GetPageRoute(
  502 + page: Center(
  503 + child: Scaffold(
  504 + appBar: AppBar(
  505 + title: Text("Main"),
  506 + ),
  507 + body: Center(
  508 + child: Text("second")
  509 + ),
  510 + ),
  511 + ),
  512 + );
  513 + }
  514 + }
  515 +),
  516 +```