Nipodemos

last changes, ready to merge

@@ -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
@@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
42 42
43 ## State management 43 ## State management
44 44
45 -**See an more in-depth explanation of state management [here](./docs/en_US/route_management.md). There you will see more examples and also the differente between the simple stage manager and the reactive state manager** 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**
46 46
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. 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.
48 48
@@ -107,7 +107,7 @@ This is a simple project but it already makes clear how powerful Get is. As your @@ -107,7 +107,7 @@ This is a simple project but it already makes clear how powerful Get is. As your
107 107
108 ## Route management 108 ## Route management
109 109
110 -**See a more in-depth explanation of route management [here](./docs/en_US/route_management.md)** 110 +See a more in-depth explanation of route management [here](./docs/en_US/route_management.md)
111 111
112 If you are going to use routes/snackbars/dialogs/bottomsheets without context, GetX is excellent for you too, just see it: 112 If you are going to use routes/snackbars/dialogs/bottomsheets without context, GetX is excellent for you too, just see it:
113 113
@@ -157,7 +157,7 @@ Noticed that you didn't had to use context to do any of these things? That's one @@ -157,7 +157,7 @@ Noticed that you didn't had to use context to do any of these things? That's one
157 157
158 ## Dependency management 158 ## Dependency management
159 159
160 -**See a more in-depth explanation of dependency management [here](./docs/en_US/dependency_management.md)** 160 +See a more in-depth explanation of dependency management [here](./docs/en_US/dependency_management.md)
161 161
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. 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.
163 163
@@ -136,11 +136,11 @@ Melhore seus prazos, entregue tudo a tempo sem perder performance. Get não é p @@ -136,11 +136,11 @@ Melhore seus prazos, entregue tudo a tempo sem perder performance. Get não é p
136 136
137 ### Explicação completa 137 ### Explicação completa
138 138
139 -**Veja uma explicação mais completa do gerenciamento de estado [aqui](./docs/pt_BR/route_management.md)** 139 +**Veja uma explicação mais completa do gerenciamento de estado [aqui](./docs/pt_BR/state_management.md)**
140 140
141 ## Gerenciamento de rotas 141 ## Gerenciamento de rotas
142 142
143 -Veja uma explicação mais completa do gerenciamento de estado [aqui](./docs/pt_BR/state_management.md) 143 +Veja uma explicação mais completa do gerenciamento de estado [aqui](./docs/pt_BR/route_management.md)
144 144
145 Para navegar para uma próxima tela: 145 Para navegar para uma próxima tela:
146 146
@@ -178,9 +178,9 @@ var dados = await Get.to(Pagamento()); @@ -178,9 +178,9 @@ var dados = await Get.to(Pagamento());
178 178
179 ## Gerenciamento de Dependência 179 ## Gerenciamento de Dependência
180 180
181 -**Veja uma explicação mais completa do gerenciamento de estado [aqui](./docs/pt_BR/dependency_management.md)** 181 +**Veja uma explicação mais completa do gerenciamento de dependência [aqui](./docs/pt_BR/dependency_management.md)**
182 182
183 -- 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ê.
184 184
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: 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:
186 186
@@ -220,7 +220,7 @@ Get.lazyPut<Service>(()=> ApiMock()); @@ -220,7 +220,7 @@ Get.lazyPut<Service>(()=> ApiMock());
220 220
221 ### Explicação completa 221 ### Explicação completa
222 222
223 -**Veja uma explicação mais completa do gerenciamento de estado [aqui](./docs/pt_BR/dependency_management.md)** 223 +**Veja uma explicação mais completa do gerenciamento de dependência [aqui](./docs/pt_BR/dependency_management.md)**
224 224
225 # Utilidades 225 # Utilidades
226 226
  1 +
  2 +# Gestión de dependencias
  3 +
  4 +## Simple Instance Manager
  5 +
  6 +- 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.
  7 +
  8 +¿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:
  9 +
  10 +```dart
  11 +Controller controller = Get.put(Controller()); // Rather Controller controller = Controller();
  12 +```
  13 +
  14 +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.
  15 +
  16 +```dart
  17 +controller.fetchApi();
  18 +```
  19 +
  20 +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:
  21 +
  22 +```dart
  23 +Controller controller = Get.find();
  24 +//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.
  25 +```
  26 +
  27 +Y luego podrá recuperar los datos de su controlador que se obtuvieron allí:
  28 +
  29 +```dart
  30 +Text(controller.textFromApi);
  31 +```
  32 +
  33 +¿Buscando lazy loading? Puede declarar todos sus controladores, y se llamará solo cuando alguien lo necesite. Puedes hacer esto con:
  34 +
  35 +```dart
  36 +Get.lazyPut<Service>(()=> ApiMock());
  37 +/// ApiMock will only be called when someone uses Get.find<Service> for the first time
  38 +```
  39 +
  40 +Si desea registrar una instancia asincrónica, puede usar Get.putAsync.
  41 +
  42 +```dart
  43 +Get.putAsync<SharedPreferences>(() async {
  44 + final prefs = await SharedPreferences.getInstance();
  45 + await prefs.setInt('counter', 12345);
  46 + return prefs;
  47 +});
  48 +```
  49 +
  50 +uso:
  51 +
  52 +```dart
  53 + int count = Get.find<SharedPreferences>().getInt('counter');
  54 + print(count);
  55 + // out: 12345
  56 +}
  57 +```
  58 +
  59 +Para eliminar una instancia de GetX:
  60 +
  61 +```dart
  62 +Get.delete<Controller>();
  63 +```
  64 +
  65 +## Bindings
  66 +
  67 +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.
  68 +
  69 +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.
  70 +
  71 +En la versión 2.10 GetX se implementó por completo la API de bindings.
  72 +
  73 +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.
  74 +
  75 +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.
  76 +
  77 +Esto permite conocer qué pantalla se muestra cuando se utiliza un controlador en particular y saber dónde y cómo descartarlo.
  78 +
  79 +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.
  80 +
  81 +### Cómo utilizar
  82 +
  83 +- Crea una clase e implementa Binding
  84 +
  85 +```dart
  86 +class HomeBinding implements Bindings{
  87 +```
  88 +
  89 +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:
  90 +
  91 +```dart
  92 +class HomeBinding implements Bindings{
  93 + @override
  94 + void dependencies() {
  95 + Get.lazyPut<ControllerX>(() => ControllerX());
  96 + Get.lazyPut<Service>(()=> Api());
  97 + }
  98 +}
  99 +```
  100 +
  101 +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.
  102 +
  103 +- Uso de rutas nombradas:
  104 +
  105 +```dart
  106 +namedRoutes: {
  107 + '/': GetRoute(Home(), binding: HomeBinding())
  108 +}
  109 +```
  110 +
  111 +- Usando rutas normales:
  112 +
  113 +```dart
  114 +Get.to(Home(), binding: HomeBinding());
  115 +```
  116 +
  117 +Allí, ya no tiene que preocuparse por la administración de memoria de su aplicación, GetX lo hará por usted.
  118 +
  119 +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.
  120 +
  121 +```dart
  122 +GetMaterialApp(
  123 + initialBinding: SampleBind(),
  124 + home: Home(),
  125 +);
  126 +```
  127 +
  128 +## SmartManagement
  129 +
  130 +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.
  131 +
  132 +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.
  133 +
  134 +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.
  135 +
  136 +Con el comportamiento predeterminado, incluso los widgets instanciados con "Get.put" se eliminarán, a diferencia de SmartManagement.onlyBuilders.
  137 +
  138 +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.
  139 +
  140 +En lugar de usar SmartManagement.keepFactory, puede usar Bindings.
  141 +
  142 +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.
  143 +
  144 +- 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.
  145 +
  146 +- 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.
  147 +
  148 +Sin embargo, si trabaja con Servicios o cualquier otra abstracción, le recomiendo usar binding para una organización más grande.
  1 +
  2 +# Gestión de Rutas
  3 +
  4 +Cualquier contribución es bienvenida!
  5 +
  6 +## ¿Cómo utilizarlo
  7 +
  8 +Agregue esto a su archivo pubspec.yaml:
  9 +
  10 +```yaml
  11 +dependencies:
  12 + get:
  13 +```
  14 +
  15 +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!
  16 +
  17 +```dart
  18 +GetMaterialApp( // Before: MaterialApp(
  19 + home: MyHome(),
  20 +)
  21 +```
  22 +
  23 +## Navegación sin rutas nombradas
  24 +
  25 +Para navegar a una nueva pantalla:
  26 +
  27 +```dart
  28 +Get.to(NextScreen());
  29 +```
  30 +
  31 +Para cerrar snackbars, dialogs, bottomsheets o cualquier cosa que normalmente cierre con Navigator.pop(contexto);
  32 +
  33 +```dart
  34 +Get.back();
  35 +```
  36 +
  37 +Para ir a la siguiente pantalla, sin opción a volver (util por ejemplo en SplashScreens, LoginScreen, etc.)
  38 +
  39 +```dart
  40 +Get.off(NextScreen());
  41 +```
  42 +
  43 +Para ir a la siguiente pantalla y cancelar todas las rutas anteriores (útil en carritos de compras, encuestas y exámenes)
  44 +
  45 +```dart
  46 +Get.offAll(NextScreen());
  47 +```
  48 +
  49 +Para navegar a la siguiente ruta y recibir o actualizar datos tan pronto como se regrese de ella:
  50 +
  51 +```dart
  52 +var data = await Get.to(Payment());
  53 +```
  54 +
  55 +en la otra pantalla, envíe los datos para la ruta anterior:
  56 +
  57 +```dart
  58 +Get.back(result: 'success');
  59 +```
  60 +
  61 +Y luego usarlo:
  62 +
  63 +ej:
  64 +
  65 +```dart
  66 +if(data == 'success') madeAnything();
  67 +```
  68 +
  69 +¿No quieres aprender nuestra sintaxis?
  70 +
  71 +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.
  72 +
  73 +Ejemplo:
  74 +
  75 +```dart
  76 +// Default Flutter navigator
  77 +Navigator.of(context).push(
  78 + context,
  79 + MaterialPageRoute(
  80 + builder: (BuildContext context) {
  81 + return HomePage();
  82 + },
  83 + ),
  84 +);
  85 +
  86 +// Get using Flutter syntax without needing context
  87 +navigator.push(
  88 + MaterialPageRoute(
  89 + builder: (_) {
  90 + return HomePage();
  91 + },
  92 + ),
  93 +);
  94 +
  95 +// Get syntax (It is much better, but you have the right to disagree)
  96 +Get.to(HomePage());
  97 +```
  98 +
  99 +## Navegación con rutas nombradas
  100 +
  101 +- Si prefiere navegar con rutas nombradas, con GetX también es posible.
  102 +
  103 +Para navegar a la siguiente pantalla
  104 +
  105 +```dart
  106 +Get.toNamed("/NextScreen");
  107 +```
  108 +
  109 +Para navegar y eliminar la pantalla anterior del árbol.
  110 +
  111 +```dart
  112 +Get.offNamed("/NextScreen");
  113 +```
  114 +
  115 +Para navegar y eliminar todas las pantallas anteriores del árbol.
  116 +
  117 +```dart
  118 +Get.offAllNamed("/NextScreen");
  119 +```
  120 +
  121 +Para definir rutas, use GetMaterialApp:
  122 +
  123 +```dart
  124 +void main() {
  125 + runApp(
  126 + GetMaterialApp(
  127 + initialRoute: '/',
  128 + getPages: [
  129 + GetPage(name: '/', page: () => MyHomePage()),
  130 + GetPage(name: '/second', page: () => Second()),
  131 + GetPage(
  132 + name: '/third',
  133 + page: () => Third(),
  134 + transition: Transition.zoom
  135 + ),
  136 + ],
  137 + )
  138 + );
  139 +}
  140 +```
  141 +
  142 +### Enviar datos a rutas nombradas
  143 +
  144 +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.
  145 +
  146 +```dart
  147 +Get.toNamed("/NextScreen", arguments: 'Get is the best');
  148 +```
  149 +
  150 +luego en su clase o controlador:
  151 +
  152 +```dart
  153 +print(Get.arguments);
  154 +//print out: Get is the best
  155 +```
  156 +
  157 +### Enlaces de URL dinámicos
  158 +
  159 +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.
  160 +
  161 +```dart
  162 +Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo");
  163 +```
  164 +
  165 +y luego en su clase controller/bloc/stateful/stateless:
  166 +
  167 +```dart
  168 +print(Get.parameters['id']);
  169 +// out: 354
  170 +print(Get.parameters['name']);
  171 +// out: Enzo
  172 +```
  173 +
  174 +También puede recibir parámetros nombrados fácilmente:
  175 +
  176 +```dart
  177 +void main() {
  178 + runApp(
  179 + GetMaterialApp(
  180 + initialRoute: '/',
  181 + getPages: [
  182 + GetPage(
  183 + name: '/',
  184 + page: () => MyHomePage(),
  185 + ),
  186 + GetPage(
  187 + name: '/profile/',
  188 + page: () => MyProfile(),
  189 + ),
  190 + //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.
  191 + GetPage(
  192 + name: '/profile/:user',
  193 + page: () => UserProfile(),
  194 + ),
  195 + GetPage(
  196 + name: '/third',
  197 + page: () => Third(),
  198 + transition: Transition.cupertino
  199 + ),
  200 + ],
  201 + )
  202 + );
  203 +}
  204 +```
  205 +
  206 +Enviar datos sobre el nombre de la ruta
  207 +
  208 +```dart
  209 +Get.toNamed("/second/34954");
  210 +```
  211 +
  212 +Y en la segunda pantalla tome los datos por parámetro
  213 +
  214 +```dart
  215 +print(Get.parameters['user']);
  216 +// out: 34954
  217 +```
  218 +
  219 +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
  220 +
  221 +### Middleware
  222 +
  223 +Si desea escuchar eventos de GetX para activar acciones, puede usar el routingCallback:
  224 +
  225 +```dart
  226 +GetMaterialApp(
  227 + routingCallback: (routing) {
  228 + if(routing.current == '/second'){
  229 + openAds();
  230 + }
  231 + }
  232 +)
  233 +```
  234 +
  235 +Si no está usando GetMaterialApp, puede usar la API para adjuntar el observador de Middleware.
  236 +
  237 +```dart
  238 +void main() {
  239 + runApp(
  240 + MaterialApp(
  241 + onGenerateRoute: Router.generateRoute,
  242 + initialRoute: "/",
  243 + navigatorKey: Get.key,
  244 + navigatorObservers: [
  245 + GetObserver(MiddleWare.observer), // HERE !!!
  246 + ],
  247 + ),
  248 + );
  249 +}
  250 +```
  251 +
  252 +Crear la clase MiddleWare:
  253 +
  254 +```dart
  255 +class MiddleWare {
  256 + static observer(Routing routing) {
  257 + /// You can listen in addition to the routes, the snackbars, dialogs and bottomsheets on each screen.
  258 + ///If you need to enter any of these 3 events directly here,
  259 + ///you must specify that the event is != Than you are trying to do.
  260 + if (routing.current == '/second' && !routing.isSnackbar) {
  261 + Get.snackbar("Hi", "You are on second route");
  262 + } else if (routing.current =='/third'){
  263 + print('last route called');
  264 + }
  265 + }
  266 +}
  267 +```
  268 +
  269 +Ahora, usa GetX en tu código:
  270 +
  271 +```dart
  272 +class First extends StatelessWidget {
  273 + @override
  274 + Widget build(BuildContext context) {
  275 + return Scaffold(
  276 + appBar: AppBar(
  277 + leading: IconButton(
  278 + icon: Icon(Icons.add),
  279 + onPressed: () {
  280 + Get.snackbar("hi", "i am a modern snackbar");
  281 + },
  282 + ),
  283 + title: Text('First Route'),
  284 + ),
  285 + body: Center(
  286 + child: RaisedButton(
  287 + child: Text('Open route'),
  288 + onPressed: () {
  289 + Get.toNamed("/second");
  290 + },
  291 + ),
  292 + ),
  293 + );
  294 + }
  295 +}
  296 +
  297 +class Second extends StatelessWidget {
  298 + @override
  299 + Widget build(BuildContext context) {
  300 + return Scaffold(
  301 + appBar: AppBar(
  302 + leading: IconButton(
  303 + icon: Icon(Icons.add),
  304 + onPressed: () {
  305 + Get.snackbar("hi", "i am a modern snackbar");
  306 + },
  307 + ),
  308 + title: Text('second Route'),
  309 + ),
  310 + body: Center(
  311 + child: RaisedButton(
  312 + child: Text('Open route'),
  313 + onPressed: () {
  314 + Get.toNamed("/third");
  315 + },
  316 + ),
  317 + ),
  318 + );
  319 + }
  320 +}
  321 +
  322 +class Third extends StatelessWidget {
  323 + @override
  324 + Widget build(BuildContext context) {
  325 + return Scaffold(
  326 + appBar: AppBar(
  327 + title: Text("Third Route"),
  328 + ),
  329 + body: Center(
  330 + child: RaisedButton(
  331 + onPressed: () {
  332 + Get.back();
  333 + },
  334 + child: Text('Go back!'),
  335 + ),
  336 + ),
  337 + );
  338 + }
  339 +}
  340 +```
  341 +
  342 +## Navegación sin contexto
  343 +
  344 +### SnackBars
  345 +
  346 +Para tener simple SnackBar con Flutter, debe obtener el contexto de Scaffold, o debe utilizar una GlobalKey:
  347 +
  348 +```dart
  349 +final snackBar = SnackBar(
  350 + content: Text('Hi!'),
  351 + action: SnackBarAction(
  352 + label: 'I am a old and ugly snackbar :(',
  353 + onPressed: (){}
  354 + ),
  355 +);
  356 +// Find the Scaffold in the widget tree and use
  357 +// it to show a SnackBar.
  358 +Scaffold.of(context).showSnackBar(snackBar);
  359 +```
  360 +
  361 +Con GetX esto se resume en:
  362 +
  363 +```dart
  364 +Get.snackbar('Hi', 'i am a modern snackbar');
  365 +```
  366 +
  367 +Todo lo que tiene que hacer es llamar a Get.snackbar desde cualquier parte de su código y personalizarlo como desee:
  368 +
  369 +```dart
  370 +Get.snackbar(
  371 + "Hey i'm a Get SnackBar!", // title
  372 + "It's unbelievable! I'm using SnackBar without context, without boilerplate, without Scaffold, it is something truly amazing!", // message
  373 + icon: Icon(Icons.alarm),
  374 + shouldIconPulse: true,
  375 + onTap:(){},
  376 + barBlur: 20,
  377 + isDismissible: true,
  378 + duration: Duration(seconds: 3),
  379 +);
  380 +
  381 +
  382 + ////////// ALL FEATURES //////////
  383 + // Color colorText,
  384 + // Duration duration,
  385 + // SnackPosition snackPosition,
  386 + // Widget titleText,
  387 + // Widget messageText,
  388 + // bool instantInit,
  389 + // Widget icon,
  390 + // bool shouldIconPulse,
  391 + // double maxWidth,
  392 + // EdgeInsets margin,
  393 + // EdgeInsets padding,
  394 + // double borderRadius,
  395 + // Color borderColor,
  396 + // double borderWidth,
  397 + // Color backgroundColor,
  398 + // Color leftBarIndicatorColor,
  399 + // List<BoxShadow> boxShadows,
  400 + // Gradient backgroundGradient,
  401 + // FlatButton mainButton,
  402 + // OnTap onTap,
  403 + // bool isDismissible,
  404 + // bool showProgressIndicator,
  405 + // AnimationController progressIndicatorController,
  406 + // Color progressIndicatorBackgroundColor,
  407 + // Animation<Color> progressIndicatorValueColor,
  408 + // SnackStyle snackStyle,
  409 + // Curve forwardAnimationCurve,
  410 + // Curve reverseAnimationCurve,
  411 + // Duration animationDuration,
  412 + // double barBlur,
  413 + // double overlayBlur,
  414 + // Color overlayColor,
  415 + // Form userInputForm
  416 + ///////////////////////////////////
  417 +```
  418 +
  419 +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.
  420 +
  421 +### Diálogos
  422 +
  423 +Para abrir el dialog:
  424 +
  425 +```dart
  426 +Get.dialog(YourDialogWidget());
  427 +```
  428 +
  429 +Para abrir un dialog predeterminado:
  430 +
  431 +```dart
  432 +Get.defaultDialog(
  433 + onConfirm: () => print("Ok"),
  434 + middleText: "Dialog made in 3 lines of code"
  435 +);
  436 +```
  437 +
  438 +También puede usar Get.generalDialog en lugar de showGeneralDialog.
  439 +
  440 +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.
  441 +
  442 +Para los widgets que no usan Overlay, puede usar Get.context.
  443 +
  444 +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.
  445 +
  446 +### BottomSheets
  447 +
  448 +Get.bottomSheet es como showModalBottomSheet, pero no necesita contexto.
  449 +
  450 +```dart
  451 +Get.bottomSheet(
  452 + Container(
  453 + child: Wrap(
  454 + children: <Widget>[
  455 + ListTile(
  456 + leading: Icon(Icons.music_note),
  457 + title: Text('Music'),
  458 + onTap: () => {}
  459 + ),
  460 + ListTile(
  461 + leading: Icon(Icons.videocam),
  462 + title: Text('Video'),
  463 + onTap: () => {},
  464 + ),
  465 + ],
  466 + ),
  467 + );
  468 +);
  469 +```
  470 +
  471 +## Navegación anidada
  472 +
  473 +GetX hizo la navegación anidada de Flutter aún más fácil.
  474 +
  475 +No necesita el contexto, y encontrará su pila de navegación por Id.
  476 +
  477 +- 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.
  478 +
  479 +Mira qué simple es:
  480 +
  481 +```dart
  482 +Navigator(
  483 + key: Get.nestedKey(1), // create a key by index
  484 + initialRoute: '/',
  485 + onGenerateRoute: (settings) {
  486 + if (settings.name == '/') {
  487 + return GetPageRoute(
  488 + page: Scaffold(
  489 + appBar: AppBar(
  490 + title: Text("Main"),
  491 + ),
  492 + body: Center(
  493 + child: FlatButton(
  494 + color: Colors.blue,
  495 + onPressed: () {
  496 + Get.toNamed('/second', id:1); // navigate by your nested route by index
  497 + },
  498 + child: Text("Go to second"),
  499 + ),
  500 + ),
  501 + ),
  502 + );
  503 + } else if (settings.name == '/second') {
  504 + return GetPageRoute(
  505 + page: Center(
  506 + child: Scaffold(
  507 + appBar: AppBar(
  508 + title: Text("Main"),
  509 + ),
  510 + body: Center(
  511 + child: Text("second")
  512 + ),
  513 + ),
  514 + ),
  515 + );
  516 + }
  517 + }
  518 +),
  519 +```
  1 +
  2 +# Gestión del Estado
  3 +
  4 +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.
  5 +
  6 +Otros state managers son buenos, pero tienen sus matices:
  7 +
  8 +- BLoC es muy seguro y eficiente, pero es muy complejo para principiantes, lo que ha impedido que las personas se desarrollen con Flutter.
  9 +
  10 +- 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!).
  11 +
  12 +- 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.
  13 +
  14 +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.
  15 +
  16 +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.
  17 +
  18 +## Gestor de Estado Simple
  19 +
  20 +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.
  21 +
  22 +### Ventajas
  23 +
  24 +1. Actualiza solo los widgets necesarios.
  25 +
  26 +2. No usa changeNotifier, es el gestor de estados que usa menos memoria (cerca de 0mb).
  27 +
  28 +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.
  29 +
  30 +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.
  31 +
  32 +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.
  33 +
  34 +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.
  35 +
  36 +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).
  37 +
  38 +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.
  39 +
  40 +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.
  41 +
  42 +### Uso
  43 +
  44 +```dart
  45 +// Create controller class and extends GetXController
  46 +class Controller extends GetXController {
  47 + int counter = 0;
  48 + void increment() {
  49 + counter++;
  50 + update(); // use update() to update counter variable on UI when increment be called
  51 + }
  52 +}
  53 +// On your Stateless/Stateful class, use GetBuilder to update Text when increment be called
  54 +GetBuilder<Controller>(
  55 + init: Controller(), // INIT IT ONLY THE FIRST TIME
  56 + builder: (_) => Text(
  57 + '${_.counter}',
  58 + ),
  59 +)
  60 +//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.
  61 +```
  62 +
  63 +**¡Listo!**
  64 +
  65 +- Ya has aprendido a gestionar estados con GetX.
  66 +
  67 +- 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.
  68 +
  69 +Si navega por muchas rutas y necesita datos que estaban en su Controller utilizado previamente, solo necesita usar nuevamente GetBuilder (sin init):
  70 +
  71 +```dart
  72 +class OtherClass extends StatelessWidget {
  73 + @override
  74 + Widget build(BuildContext context) {
  75 + return Scaffold(
  76 + body: Center(
  77 + child: GetBuilder<Controller>(
  78 + builder: (s) => Text('${s.counter}'),
  79 + ),
  80 + ),
  81 + );
  82 + }
  83 +```
  84 +
  85 +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>()`)
  86 +
  87 +```dart
  88 +class Controller extends GetXController {
  89 +
  90 + /// You do not need that. I recommend using it just for ease of syntax.
  91 + /// with static method: Controller.to.counter();
  92 + /// with no static method: Get.find<Controller>().counter();
  93 + /// 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.
  94 + static Controller get to => Get.find(); // add this line
  95 +
  96 + int counter = 0;
  97 + void increment() {
  98 + counter++;
  99 + update();
  100 + }
  101 +}
  102 +```
  103 +
  104 +Y luego puede acceder a su Controller directamente, de esa manera:
  105 +
  106 +```dart
  107 +FloatingActionButton(
  108 + onPressed: () {
  109 + Controller.to.increment(),
  110 + } // This is incredibly simple!
  111 + child: Text("${Controller.to.counter}"),
  112 +),
  113 +```
  114 +
  115 +Cuando presiona FloatingActionButton, todos los widgets que escuchan la variable 'counter' se actualizarán automáticamente.
  116 +
  117 +### Cómo maneja los Controllers
  118 +
  119 +Digamos que tenemos esto:
  120 +
  121 +`Class a => Class B (has controller X) => Class C (has controller X)`
  122 +
  123 +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.
  124 +
  125 +### Ya no necesitará StatefulWidgets
  126 +
  127 +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.
  128 +
  129 +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!
  130 +A menos que necesite usar un mixin, como TickerProviderStateMixin, será totalmente innecesario usar un StatefulWidget con GetX.
  131 +
  132 +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;
  133 +
  134 +```dart
  135 +GetBuilder<Controller>(
  136 + initState: (_) => Controller.to.fetchApi(),
  137 + dispose: (_) => Controller.to.closeStreams(),
  138 + builder: (s) => Text('${s.username}'),
  139 +),
  140 +```
  141 +
  142 +Un enfoque mucho mejor que esto es utilizar el método onInit() y onClose() directamente desde su Controller.
  143 +
  144 +```dart
  145 +@override
  146 +void onInit() {
  147 + fetchApi();
  148 + super.onInit();
  149 +}
  150 +```
  151 +
  152 +- 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.
  153 +
  154 +### Por qué existe
  155 +
  156 +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.
  157 +
  158 +Entonces, para simplificar esto:
  159 +
  160 +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.
  161 +
  162 +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.
  163 +
  164 +Ejemplo:
  165 +
  166 +```dart
  167 +class Controller extends GetXController {
  168 + StreamController<User> user = StreamController<User>();
  169 + StreamController<String> name = StreamController<String>();
  170 +
  171 + /// close stream = onClose method, not dispose.
  172 + @override
  173 + void onClose() {
  174 + user.close();
  175 + name.close();
  176 + super.onClose();
  177 + }
  178 +}
  179 +```
  180 +
  181 +Ciclo de vida del Controller:
  182 +
  183 +- onInit() donde se crea.
  184 +- onClose() donde está cerrado para cualquier tipo de modificación en preparación para ser removido.
  185 +- deleted: no tiene acceso a esta API porque literalmente el Controller está eliminando de la memoria, sin dejar rastro (literal).
  186 +
  187 +### Otras formas de usarlo
  188 +
  189 +Puede usar la instancia de Controller directamente en el value de GetBuilder:
  190 +
  191 +```dart
  192 +GetBuilder<Controller>(
  193 + init: Controller(),
  194 + builder: (value) => Text(
  195 + '${value.counter}', //here
  196 + ),
  197 +),
  198 +```
  199 +
  200 +También puede necesitar una instancia de su Controller fuera de su GetBuilder, y puede usar estos enfoques para lograr esto:
  201 +
  202 +```dart
  203 +class Controller extends GetXController {
  204 + static Controller get to => Get.find();
  205 +[...]
  206 +}
  207 +// on you view:
  208 +GetBuilder<Controller>(
  209 + init: Controller(), // use it only first time on each controller
  210 + builder: (_) => Text(
  211 + '${Controller.to.counter}', //here
  212 + )
  213 +),
  214 +```
  215 +
  216 +o
  217 +
  218 +```dart
  219 +class Controller extends GetXController {
  220 + // static Controller get to => Get.find(); // with no static get
  221 +[...]
  222 +}
  223 +// on stateful/stateless class
  224 +GetBuilder<Controller>(
  225 + init: Controller(), // use it only first time on each controller
  226 + builder: (_) => Text(
  227 + '${Get.find<Controller>().counter}', //here
  228 + ),
  229 +),
  230 +```
  231 +
  232 +- 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:
  233 +
  234 +```dart
  235 +Controller controller = Controller();
  236 +[...]
  237 +GetBuilder<Controller>(
  238 + init: controller, //here
  239 + builder: (_) => Text(
  240 + '${controller.counter}', // here
  241 + ),
  242 +),
  243 +```
  244 +
  245 +### ID únicos
  246 +
  247 +Si desea refinar el control de actualización de widgets con GetBuilder, puede asignarles ID únicos:
  248 +
  249 +```dart
  250 +GetBuilder<Controller>(
  251 + id: 'text'
  252 + init: Controller(), // use it only first time on each controller
  253 + builder: (_) => Text(
  254 + '${Get.find<Controller>().counter}', //here
  255 + ),
  256 +),
  257 +```
  258 +
  259 +Y actualízalo de esta forma:
  260 +
  261 +```dart
  262 +update(['text']);
  263 +```
  264 +
  265 +También puede imponer condiciones para la actualización:
  266 +
  267 +```dart
  268 +update(['text'], counter < 10);
  269 +```
  270 +
  271 +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).
  272 +
  273 +## Reactivo STATE_MANAGER
  274 +
  275 +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!).
  276 +
  277 +Imaginemos que tiene una variable "name" y desea que cada vez que la modifique, todos los widgets que la usan cambien automáticamente.
  278 +
  279 +Ej. esta es tu variable "name":
  280 +
  281 +```dart
  282 +var name = 'Jonatas Borges';
  283 +```
  284 +
  285 +Para que sea observable, solo necesita agregar ".obs" al final:
  286 +
  287 +```dart
  288 +var name = 'Jonatas Borges'.obs;
  289 +```
  290 +
  291 +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.
  292 +
  293 +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?
  294 +No, no necesitas un StreamBuilder, pero tienes razón sobre las clases estáticas.
  295 +
  296 +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.
  297 +
  298 +```dart
  299 +Obx(() => Text (controller.name));
  300 +```
  301 +
  302 +¿Qué necesitas memorizar? "Obx(() =>"
  303 +
  304 +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?
  305 +
  306 +¿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.
  307 +
  308 +### Ventajas
  309 +
  310 +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.
  311 +
  312 +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.
  313 +
  314 +Puede usar ambos en cualquier situación, pero si desea ajustar su aplicación al máximo rendimiento posible, diría que:
  315 +
  316 +- 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,
  317 +- 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.
  318 +
  319 +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.
  320 +
  321 +Si quieres poder, GetX te ofrece el gestor de estado más avanzado que puedas tener.
  322 +
  323 +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.
  324 +
  325 +Sin decoraciones, puede convertir cualquier cosa en Observable con solo un ".obs".
  326 +
  327 +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.
  328 +
  329 +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.
  330 +
  331 +### Uso
  332 +
  333 +Tienes 3 formas de convertir una variable en observable.
  334 +
  335 +El primero es usar Rx{Type}.
  336 +
  337 +```dart
  338 +var count = RxString();
  339 +```
  340 +
  341 +El segundo es usar Rx y escribirlo con `Rx<Type>`
  342 +
  343 +```dart
  344 +var count = Rx<String>();
  345 +```
  346 +
  347 +El tercer enfoque, más práctico, fácil e increíble, es simplemente agregar un .obs a su variable.
  348 +
  349 +```dart
  350 +var count = 0.obs;
  351 +
  352 +// or Rxint count = 0.obs;
  353 +// or Rx<int> count = 0.obs;
  354 +```
  355 +
  356 +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.
  357 +
  358 +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!
  359 +
  360 +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
  361 +
  362 +```dart
  363 +final count1 = 0.obs;
  364 +final count2 = 0.obs;
  365 +int get sum => count1.value + count2.value;
  366 +```
  367 +
  368 +```dart
  369 +GetX<Controller>(
  370 + builder: (value) {
  371 + print("count 1 rebuild");
  372 + return Text('${value.count1.value}');
  373 + },
  374 +),
  375 +GetX<Controller>(
  376 + builder: (_) {
  377 + print("count 2 rebuild");
  378 + return Text('${_.count2.value}');
  379 + },
  380 +),
  381 +GetX<Controller>(
  382 + builder: (_) {
  383 + print("count 3 rebuild");
  384 + return Text('${_.sum}');
  385 + },
  386 +),
  387 +```
  388 +
  389 +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.
  390 +
  391 +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.
  392 +
  393 +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.
  394 +
  395 +- NOTA: Por defecto, el primer evento permitirá la reconstrucción incluso si es igual. Creamos este comportamiento debido a variables dualistas, como Boolean.
  396 +
  397 +Imaginemos que hiciste esto:
  398 +
  399 +```dart
  400 +var isLogged = false.obs;
  401 +```
  402 +
  403 +y luego verifica si un usuario ha iniciado sesión para activar un evento en "ever".
  404 +
  405 +```dart
  406 +onInit(){
  407 + ever(isLogged, fireRoute);
  408 + isLogged.value = await Preferences.hasToken();
  409 +}
  410 +
  411 +fireRoute(logged) {
  412 + if (logged) {
  413 + Get.off(Home());
  414 + } else {
  415 + Get.off(Login());
  416 + }
  417 +}
  418 +```
  419 +
  420 +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.
  421 +
  422 +Puede eliminar este comportamiento si lo desea, utilizando:
  423 +`isLogged.firstRebuild = false;`
  424 +
  425 +Además, GetX proporciona control de estado refinado. Puede condicionar un evento (como agregar un objeto a una lista), en una determinada condición:
  426 +
  427 +```dart
  428 +list.addIf(item < limit, item);
  429 +```
  430 +
  431 +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!
  432 +
  433 +¿Conoces el counter de Flutter? Su clase de controlador podría verse así:
  434 +
  435 +```dart
  436 +class CountCtl extends GetxController {
  437 + final count = 0.obs;
  438 +}
  439 +```
  440 +
  441 +Con un simple:
  442 +
  443 +```dart
  444 +ctl.count.value++
  445 +```
  446 +
  447 +Puede actualizar la variable de contador en su IU, independientemente de dónde esté almacenada.
  448 +
  449 +### Donde se pueden usar .obs
  450 +
  451 +Puedes transformar cualquier cosa en obs:
  452 +
  453 +```dart
  454 +class RxUser {
  455 + final name = "Camila".obs;
  456 + final age = 18.obs;
  457 +}
  458 +
  459 +class User {
  460 + User({String name, int age});
  461 + final rx = RxUser();
  462 +
  463 + String get name => rx.name.value;
  464 + set name(String value) => rx.name.value = value;
  465 +
  466 + int get age => rx.age.value;
  467 + set age(int value) => rx.age.value = value;
  468 +}
  469 +```
  470 +
  471 +```dart
  472 +void main() {
  473 + final user = User();
  474 + print(user.name);
  475 + user.age = 23;
  476 + user.rx.age.listen((int age) => print(age));
  477 + user.age = 24;
  478 + user.age = 25;
  479 +}
  480 +___________
  481 +out:
  482 +Camila
  483 +23
  484 +24
  485 +25
  486 +```
  487 +
  488 +### Nota sobre listas
  489 +
  490 +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.
  491 +
  492 +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.
  493 +
  494 +```dart
  495 +final list = List<User>().obs;
  496 +```
  497 +
  498 +```dart
  499 +ListView.builder (
  500 + itemCount: list.lenght
  501 +)
  502 +```
  503 +
  504 +No tiene que trabajar con Sets si no lo desea. puede usar la api "assign" y "assignAll".
  505 +
  506 +La API "assign" borrará su lista y agregará un solo objeto, con el que quiere comenzar allí.
  507 +
  508 +La API "assignAll" borrará la lista existente y agregará cualquier objeto iterable que le inyecte.
  509 +
  510 +### ¿Por qué tengo que usar .value
  511 +
  512 +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.
  513 +
  514 +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.
  515 +
  516 +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.
  517 +
  518 +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.
  519 +
  520 +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.
  521 +
  522 +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.
  523 +
  524 +### Obx()
  525 +
  526 +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.
  527 +
  528 +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.
  529 +
  530 +### Workers
  531 +
  532 +Los workers lo ayudarán, activando callbacks específicos cuando ocurra un evento.
  533 +
  534 +```dart
  535 +/// Called every time the variable $_ is changed
  536 +ever(count1, (_) => print("$_ has been changed"));
  537 +
  538 +/// Called only first time the variable $_ is changed
  539 +once(count1, (_) => print("$_ was changed once"));
  540 +
  541 +/// Anti DDos - Called every time the user stops typing for 1 second, for example.
  542 +debounce(count1, (_) => print("debouce$_"), time: Duration(seconds: 1));
  543 +
  544 +/// Ignore all changes within 1 second.
  545 +interval(count1, (_) => print("interval $_"), time: Duration(seconds: 1));
  546 +```
  547 +
  548 +- ever: se llama cada vez que se cambia su variable. Eso es.
  549 +
  550 +- once: se llama solo la primera vez que se ha cambiado la variable.
  551 +
  552 +- 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.
  553 +
  554 +- 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.
  555 +
  556 +## Mezclando los dos State Managers
  557 +
  558 +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.
  559 +
  560 +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.
  561 +
  562 +## GetBuilder vs GetX vs Obx vs MixinBuilder
  563 +
  564 +En una década trabajando con programación pude aprender algunas lecciones valiosas.
  565 +
  566 +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.
  567 +
  568 +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.
  569 +
  570 +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.
  571 +
  572 +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.
  573 +
  574 +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).
  575 +
  576 +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.
  577 +
  578 +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.
  579 +
  580 +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.