Jonatas

Unify structure again

Showing 82 changed files with 1221 additions and 3096 deletions

Too many changes to show.

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

@@ -13,7 +13,7 @@ jobs: @@ -13,7 +13,7 @@ jobs:
13 #The type of machine to run the job on. [windows,macos, ubuntu , self-hosted] 13 #The type of machine to run the job on. [windows,macos, ubuntu , self-hosted]
14 defaults: 14 defaults:
15 run: 15 run:
16 - working-directory: getx/ 16 + working-directory: ./
17 runs-on: ubuntu-latest 17 runs-on: ubuntu-latest
18 #sequence of tasks called 18 #sequence of tasks called
19 steps: 19 steps:
  1 +{
  2 + // Use o IntelliSense para aprender sobre possíveis atributos.
  3 + // Passe o mouse para ver as descrições dos atributos existentes.
  4 + // Para obter mais informações, visite: https://go.microsoft.com/fwlink/?linkid=830387
  5 + "version": "0.2.0",
  6 + "configurations": [
  7 + {
  8 + "name": "getx",
  9 + "cwd": "getx",
  10 + "request": "launch",
  11 + "type": "dart"
  12 + },
  13 + {
  14 + "name": "example debug",
  15 + "cwd": "getx/example",
  16 + "request": "launch",
  17 + "flutterMode": "debug",
  18 + "type": "dart"
  19 + },
  20 + {
  21 + "name": "example profile",
  22 + "cwd": "getx/example",
  23 + "request": "launch",
  24 + "flutterMode": "profile",
  25 + "type": "dart"
  26 + },
  27 + {
  28 + "name": "example release",
  29 + "cwd": "getx/example",
  30 + "request": "launch",
  31 + "flutterMode": "release",
  32 + "type": "dart"
  33 + },
  34 + {
  35 + "name": "get_core",
  36 + "cwd": "packages/get_core",
  37 + "request": "launch",
  38 + "type": "dart"
  39 + },
  40 + {
  41 + "name": "get_instance",
  42 + "cwd": "packages/get_instance",
  43 + "request": "launch",
  44 + "type": "dart"
  45 + },
  46 + {
  47 + "name": "get_navigation",
  48 + "cwd": "packages/get_navigation",
  49 + "request": "launch",
  50 + "type": "dart"
  51 + },
  52 + {
  53 + "name": "get_rx",
  54 + "cwd": "packages/get_rx",
  55 + "request": "launch",
  56 + "type": "dart"
  57 + },
  58 + {
  59 + "name": "get_state_manager",
  60 + "cwd": "packages/get_state_manager",
  61 + "request": "launch",
  62 + "type": "dart"
  63 + },
  64 + {
  65 + "name": "get_test",
  66 + "cwd": "packages/get_test",
  67 + "request": "launch",
  68 + "type": "dart"
  69 + },
  70 + {
  71 + "name": "get_utils",
  72 + "cwd": "packages/get_utils",
  73 + "request": "launch",
  74 + "type": "dart"
  75 + }
  76 + ]
  77 +}
1 -## [3.12.2] 1 +## [3.13.1]
  2 +- Remove spaces whitespaces from dart files
  3 +-
  4 +## [3.13.0]
2 - Fix typos on code and docs (@wbemanuel and @Goddchen) 5 - Fix typos on code and docs (@wbemanuel and @Goddchen)
3 - Improve: typedef to GetBuilder and Getx widgets 6 - Improve: typedef to GetBuilder and Getx widgets
4 - Improve behaviour of null route on lastest flutter version (@FiercestT) 7 - Improve behaviour of null route on lastest flutter version (@FiercestT)
@@ -8,7 +11,6 @@ @@ -8,7 +11,6 @@
8 - Transition.native use default Flutter transitions 11 - Transition.native use default Flutter transitions
9 - Added Get.testMode to use contextless elements on unit tests 12 - Added Get.testMode to use contextless elements on unit tests
10 - Added Get.appUpdate and improve Get.forceAppUpdate 13 - Added Get.appUpdate and improve Get.forceAppUpdate
11 --  
12 14
13 ## [3.12.1] 15 ## [3.12.1]
14 - Remove spaces whitespaces from dart files 16 - Remove spaces whitespaces from dart files
1 -# See https://www.dartlang.org/guides/libraries/private-files  
2 -  
3 -# See https://www.dartlang.org/guides/libraries/private-files  
4 -  
5 -# Files and directories created by pub  
6 -.dart_tool/  
7 -.packages  
8 -build/  
9 -# If you're building an application, you may want to check-in your pubspec.lock  
10 -pubspec.lock  
11 -.pub/  
12 -  
13 -# Directory created by dartdoc  
14 -# If you don't generate documentation locally you can remove this line.  
15 -doc/api/  
16 -  
17 -# Avoid committing generated Javascript files:  
18 -*.dart.js  
19 -*.info.json # Produced by the --dump-info flag.  
20 -*.js # When generated by dart2js. Don't specify *.js if your  
21 - # project includes source files written in JavaScript.  
22 -*.js_  
23 -*.js.deps  
24 -*.js.map  
25 -  
26 -# Files and directories created when test or run example  
27 -example/android/local.properties  
28 -example/ios/  
29 -example/.dart_tool/  
30 -example/.packages  
31 -  
32 -# IntelliJ  
33 -*.iml  
34 -.idea/*  
35 -#.idea/workspace.xml  
36 -#.idea/tasks.xml  
37 -#.idea/gradle.xml  
38 -#.idea/assetWizardSettings.xml  
39 -#.idea/dictionaries  
40 -#.idea/libraries  
41 -#.idea/caches  
42 -  
43 -# User-specific stuff  
44 -.idea/**/workspace.xml  
45 -.idea/**/tasks.xml  
46 -.idea/**/dictionaries  
47 -.idea/**/shelf  
48 -  
49 -# Sensitive or high-churn files  
50 -.idea/**/dataSources/  
51 -.idea/**/dataSources.ids  
52 -.idea/**/dataSources.local.xml  
53 -.idea/**/sqlDataSources.xml  
54 -.idea/**/dynamic.xml  
55 -.idea/**/uiDesigner.xml  
56 -.idea/**/dbnavigator.xml  
57 -  
58 -# Gradle  
59 -.idea/**/gradle.xml  
60 -.idea/**/libraries  
61 -  
62 -# Android Studio Navigation editor temp files  
63 -.navigation/  
64 -  
65 -# Android Studio captures folder  
66 -captures/  
67 -  
68 -# External native build folder generated in Android Studio 2.2 and later  
69 -.externalNativeBuild  
70 -  
71 -### https://raw.github.com/github/gitignore/80a8803b004013d17291196825a327b9e871f009/Global/VisualStudioCode.gitignore  
72 -.vscode/*  
73 -!.vscode/settings.json  
74 -!.vscode/tasks.json  
75 -!.vscode/launch.json  
76 -!.vscode/extensions.json  
77 -  
78 -example/macos/Flutter/ephemeral/Flutter-Generated.xcconfig  
79 -  
80 -example/macos/Flutter/ephemeral/  
81 -  
82 -example/macos/Flutter/GeneratedPluginRegistrant.swift  
1 -MIT License  
2 -  
3 -Copyright (c) 2019 Jonny Borges  
4 -  
5 -Permission is hereby granted, free of charge, to any person obtaining a copy  
6 -of this software and associated documentation files (the "Software"), to deal  
7 -in the Software without restriction, including without limitation the rights  
8 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
9 -copies of the Software, and to permit persons to whom the Software is  
10 -furnished to do so, subject to the following conditions:  
11 -  
12 -The above copyright notice and this permission notice shall be included in all  
13 -copies or substantial portions of the Software.  
14 -  
15 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
16 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
17 -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
18 -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
19 -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  
20 -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  
21 -SOFTWARE.  
1 -![](get.png)  
2 -  
3 -*Idiomas: Español (este archivo), [Inglés](README.md), [Portugués de Brasil](README.pt-br.md), [Polaco](README.pl.md).*  
4 -  
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)  
7 -[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart)  
8 -[![Discord Shield](https://img.shields.io/discord/722900883784073290.svg?logo=discord)](https://discord.com/invite/9Hpt99N)  
9 -[![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](https://communityinviter.com/apps/getxworkspace/getx)  
10 -[![Telegram](https://img.shields.io/badge/chat-on%20Telegram-blue.svg)](https://t.me/joinchat/PhdbJRmsZNpAqSLJL6bH7g)  
11 -<a href="https://github.com/Solido/awesome-flutter">  
12 - <img alt="Awesome Flutter" src="https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square" />  
13 -</a>  
14 -<a href="https://www.buymeacoffee.com/jonataslaw" target="_blank"><img src="https://i.imgur.com/aV6DDA7.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" > </a>  
15 -  
16 -![](getx.png)  
17 -  
18 -<h3>Lamentamos la inconsistencia en la traducción. El paquete GetX se actualiza con bastante frecuencia y es posible que las traducciones a documentos no sean tan rápidas. Entonces, para que esta documentación aún tenga todo el contenido, dejaré aquí todos los textos nuevos sin traducir (considero que es mejor tener los documentos en inglés que no tenerlos), por lo que si alguien quiere traducir, sería de gran ayuda 😁</h3>  
19 -  
20 -- [Communication and support channels:](#communication-and-support-channels)  
21 -- [Sobre GetX](#sobre-getx)  
22 -- [Como contribuir](#como-contribuir)  
23 -- [Instalando](#installing)  
24 -- [Proyecto Counter en GetX](#proyeto-counter-no-getx)  
25 -- [Los tres pilares](#los-tres-pilares)  
26 - - [Gestión del Estado](#gestión-del-estado)  
27 - - [STATE_MANAGER Reactivo](#reactivo-state_manager)  
28 - - [Más detalles sobre la gestión del estado.](#más-detalles-sobre-la-gestión-del-estado)  
29 - - [Explicación en video sobre state management](#video-explanation-about-state-management)  
30 - - [Gestión de Rutas](#gestión-de-rutas)  
31 - - [Más detalles sobre la gestión de rutas.](#más-detalles-sobre-la-gestión-de-rutas)  
32 - - [Explicación del video](#video-explanation)  
33 - - [Gestión de dependencias](#gestión-de-dependencias)  
34 - - [Más detalles sobre la gestión de dependencias.](#más-detalles-sobre-la-gestión-de-dependencias)  
35 -- [Utilidades](#utils)  
36 - - [Cambiar de tema](#cambiar-de-tema)  
37 - - [Otras API avanzadas y configuraciones manuales](#otras-api-avanzadas-y-configuraciones-manuales)  
38 - - [Configuraciones globales opcionales](#configuraciones-globales-opcionales)  
39 - - [Explicación en video de Other GetX Features](#video-explanation-of-other-getx-features)  
40 -- [Rompiendo cambios desde 2.0](#rompiendo-cambios-desde-20)  
41 -- [¿Por qué Getx?](#por-qué-getx)  
42 -  
43 -# Communication and support channels:  
44 -  
45 -[**Slack (Inglés)**](https://communityinviter.com/apps/getxworkspace/getx)  
46 -  
47 -[**Discord (Ingles y Portugués)**](https://discord.com/invite/9Y3wK9)  
48 -  
49 -[**Telegram (Portugués)**](https://t.me/joinchat/PhdbJRmsZNpAqSLJL6bH7g)  
50 -  
51 -# Sobre GetX  
52 -  
53 -- 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.  
54 -  
55 -- GetX tiene 3 principios básicos, esto significa que esta es la prioridad para todos los recursos de la biblioteca.  
56 - **PERFORMANCE:** GetX se centra en el rendimiento y el consumo mínimo de recursos. Los puntos de referencia casi siempre no son importantes en el mundo real, pero si lo desea, aquí hay un indicador de consumo.([benchmarks](https://github.com/jonataslaw/benchmarks)), donde GetX lo hace mejor que otros enfoques de gestión estatal, por ejemplo. La diferencia no es grande, pero muestra nuestra preocupación por no desperdiciar sus recursos.  
57 - **PRODUCTIVITY:** GetX utiliza una sintaxis fácil y agradable.  
58 - **ORGANIZATION:** GetX permite el desacoplamiento total de la vista de la lógica empresarial.  
59 -  
60 -* GetX ahorrará horas de desarrollo y extraerá el máximo rendimiento que su aplicación puede ofrecer, siendo fácil para los principiantes y precisa para los expertos. Navega sin contexto, abre diálogos, snackbars o bottomsheets desde cualquier lugar de tu código, gestiona estados e inyecta dependencias de forma fácil y práctica. Get es seguro, estable, actualizado y ofrece una amplia gama de API que no están presentes en el marco predeterminado.  
61 -  
62 -- GetX no es bloated. Tiene una multitud de características que le permiten comenzar a programar sin preocuparse por nada, pero cada una de estas características se encuentran en contenedores separados y solo se inician después de su uso. Si solo usa State Management, solo se compilará State Management. Si solo usa rutas, no se compilará nada de la administración estatal. Puede compilar el repositorio de referencia y verá que al usar solo la administración de estado de Get, la aplicación compilada con Get se ha vuelto más pequeña que todas las demás aplicaciones que solo tienen la administración de estado de otros paquetes, porque nada que no se use se compilará en su código, y cada solución GetX fue diseñada para ser muy liviana. El mérito aquí también proviene del movimiento del árbol de Flutter, que es increíble y logra eliminar los recursos no utilizados como ningún otro marco lo hace.  
63 -  
64 -**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)**  
65 -  
66 -# Como contribuir  
67 -  
68 -_¿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._  
69 -  
70 -- Ayudando a traducir el archivo Léame a otros idiomas.  
71 -  
72 -- Agregar documentación al archivo Léame (ni siquiera la mitad de las funciones de GetX han sido documentadas todavía).  
73 -  
74 -- 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).  
75 -  
76 -- Ofreciendo PRs para código/pruebas.  
77 -  
78 -- Incluyendo nuevas funciones.  
79 -  
80 -# Installing  
81 -  
82 -Add Get to your pubspec.yaml file:  
83 -  
84 -```yaml  
85 -dependencies:  
86 - get:  
87 -```  
88 -  
89 -Importar archivos get que se utilizarán:  
90 -  
91 -```dart  
92 -import 'package:get/get.dart';  
93 -```  
94 -  
95 -# Proyecto Counter no GetX  
96 -  
97 -Vea una explicación más detallada de la administración del estado [aquí](./documentation/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  
98 -  
99 -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.  
100 -  
101 -- Paso 1:  
102 - Agregue "Get" antes de su materialApp, convirtiéndolo en GetMaterialApp  
103 -  
104 -```dart  
105 -void main() => runApp(GetMaterialApp(home: Home()));  
106 -```  
107 -  
108 -**Nota**: esto no modifica el MaterialApp del Flutter, GetMaterialApp no es una MaterialApp modificado, es solo un Widget preconfigurado, que tiene como child un MaterialApp por defecto. Puede configurar esto manualmente, pero definitivamente no es necesario. GetMaterialApp creará rutas, las inyectará, inyectará traducciones, inyectará todo lo que necesita para la navegación de rutas. Si usa Get solo para la gestión de estado o dependencias, no es necesario usar GetMaterialApp. GetMaterialApp es necesario para rutas, snackbars, internacionalización, bottomSheets, diálogos y APIs de alto nivel relacionadas con rutas y ausencia de contexto.  
109 -  
110 -**Note²:** Este paso solo es necesario si vas a usar route management (`Get.to()`, `Get.back()` y así). Si no lo va a usar, no es necesario que realice el paso 1  
111 -  
112 -- Paso 2:  
113 - 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".  
114 -  
115 -```dart  
116 -class Controller extends GetxController {  
117 - var count = 0.obs;  
118 - increment() => count.value++;  
119 -}  
120 -```  
121 -  
122 -- Paso 3:  
123 - Cree su vista, use StatelessWidget y ahorre algo de RAM, con GetX ya no necesitará usar StatefulWidget.  
124 -  
125 -```dart  
126 -class Home extends StatelessWidget {  
127 -  
128 - // Cree una instancia de su clase usando Get.put() para que esté disponible para todas las rutas "secundarias" allí.  
129 - final Controller c = Get.put(Controller());  
130 -  
131 - @override  
132 - Widget build(context) => Scaffold(  
133 - // Utilice Obx(()=> para actualizar Text() siempre que se cambie el recuento.  
134 - appBar: AppBar(title: Obx(() => Text("Clicks: " + c.count.string))),  
135 -  
136 - // Reemplace el Navigator.push de 8 líneas por un simple Get.to(). No necesitas contexto  
137 - body: Center(child: RaisedButton(  
138 - child: Text("Go to Other"), onPressed: () => Get.to(Other()))),  
139 - floatingActionButton:  
140 - FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment));  
141 -}  
142 -  
143 -class Other extends StatelessWidget {  
144 - // Puede pedirle a Get que busque un controlador que está siendo utilizado por otra página y le redirija a él.  
145 - final Controller c = Get.find();  
146 -  
147 - @override  
148 - Widget build(context){  
149 - // Acceder a la variable de recuento actualizada  
150 - return Scaffold(body: Center(child: Text(c.count.string)));  
151 - }  
152 -}  
153 -  
154 -```  
155 -  
156 -Resultado:  
157 -  
158 -![](counter-app-gif.gif)  
159 -  
160 -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!  
161 -  
162 -# Los tres pilares  
163 -  
164 -## Gestión del Estado  
165 -  
166 -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.  
167 -  
168 -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.  
169 -  
170 -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.  
171 -  
172 -### Reactivo STATE_MANAGER  
173 -  
174 -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!).  
175 -  
176 -Imaginemos que tiene una variable "name" y desea que cada vez que la modifique, todos los widgets que la usan cambien automáticamente.  
177 -  
178 -Ej. esta es tu variable "name":  
179 -  
180 -```dart  
181 -var name = 'Jonatas Borges';  
182 -```  
183 -  
184 -Para que sea observable, solo necesita agregar ".obs" al final:  
185 -  
186 -```dart  
187 -var name = 'Jonatas Borges'.obs;  
188 -```  
189 -  
190 -¿StreamBuilder? ¿initialValue? ¿builder? No, solo necesitas jugar con esta variable dentro de un widget Obx.  
191 -  
192 -```dart  
193 -Obx(() => Text (controller.name));  
194 -```  
195 -  
196 -### Más detalles sobre la gestión del estado.  
197 -  
198 -**Vea una explicación más detallada de la administración del estado [aquí](./documentation/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**  
199 -  
200 -### Explicación en video sobre state management  
201 -  
202 -Darwin Morocho hizo una increíble serie de videos sobre state management! Link: [Complete GetX State Management](https://www.youtube.com/watch?v=PTjj0DFK8BA&list=PLV0nOzdUS5XtParoZLgKoVwNSK9zROwuO)  
203 -  
204 -Obtendrá una buena idea de la potencia de GetX.  
205 -  
206 -## Gestión de Rutas  
207 -  
208 -Para navegar a una nueva pantalla:  
209 -  
210 -```dart  
211 -Get.to(NextScreen());  
212 -```  
213 -  
214 -Para cerrar snackbars, dialogs, bottomsheets o cualquier cosa que normalmente cierre con Navigator.pop(contexto);  
215 -  
216 -```dart  
217 -Get.back();  
218 -```  
219 -  
220 -Para ir a la siguiente pantalla, sin opción a volver (util por ejemplo en SplashScreens, LoginScreen, etc.)  
221 -  
222 -```dart  
223 -Get.off(NextScreen());  
224 -```  
225 -  
226 -Para ir a la siguiente pantalla y cancelar todas las rutas anteriores (útil en carritos de compras, encuestas y exámenes)  
227 -  
228 -```dart  
229 -Get.offAll(NextScreen());  
230 -```  
231 -  
232 -Para navegar a la siguiente ruta y recibir o actualizar datos tan pronto como se regrese de ella:  
233 -  
234 -```dart  
235 -var data = await Get.to(Payment());  
236 -```  
237 -  
238 -### Más detalles sobre la gestión de rutas.  
239 -  
240 -**Vea una explicación más detallada de la Gestión de Rutas [aquí](./documentation/es_ES/route_management.md).**  
241 -  
242 -### Explicación del video  
243 -  
244 -Amateur Coder hizo un excelente video que cubre route management con Get! aquí esta el link: [Complete Getx Navigation](https://www.youtube.com/watch?v=RaqPIoJSTtI)  
245 -  
246 -## Gestión de dependencias  
247 -  
248 -- 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.  
249 -  
250 -¿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:  
251 -  
252 -```dart  
253 -Controller controller = Get.put(Controller()); // Rather Controller controller = Controller();  
254 -```  
255 -  
256 -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.  
257 -  
258 -```dart  
259 -controller.fetchApi();  
260 -```  
261 -  
262 -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 Provider o Get_it, ¿correcto? No con GetX. Solo necesita pedirle a GetX que "encuentre" su controlador, no necesita dependencias adicionales:  
263 -  
264 -```dart  
265 -Controller controller = Get.find();  
266 -//Sí, parece que es magia, Get encontrará su controlador y se lo entregará. Puede tener 1 millón de controladores instanciados, Get siempre le dará el controlador correcto.  
267 -```  
268 -  
269 -Y luego podrá recuperar los datos de su controlador que se obtuvieron allí:  
270 -  
271 -```dart  
272 -Text(controller.textFromApi);  
273 -```  
274 -  
275 -¿Buscando lazy loading? Puede declarar todos sus controladores, y se llamará solo cuando alguien lo necesite. Puedes hacer esto con:  
276 -  
277 -```dart  
278 -Get.lazyPut<Service>(()=> ApiMock());  
279 -/// ApiMock solo se llamará cuando alguien use Get.find<Service> por primera vez  
280 -```  
281 -  
282 -### Más detalles sobre la gestión de dependencias.  
283 -  
284 -**Vea una explicación más detallada de la Gestión de dependencias [aquí](./documentation/es_ES/dependency_management.md).**  
285 -  
286 -# Utilidades  
287 -  
288 -## Cambiar de tema  
289 -  
290 -No utilice ningún widget de nivel superior que GetMaterialApp para actualizarlo. Esto puede activar claves duplicadas. Mucha gente está acostumbrada al enfoque prehistórico de crear un widget "ThemeProvider" solo para cambiar el tema de su aplicación, y esto definitivamente NO es necesario con GetX.  
291 -  
292 -Puede crear su tema personalizado y simplemente agregarlo dentro de Get.changeTheme sin ningún boilerplate para eso:  
293 -  
294 -```dart  
295 -Get.changeTheme(ThemeData.light());  
296 -```  
297 -  
298 -Si desea crear algo así como un botón que cambia el tema con onTap, puede combinar dos APIs GetX para eso, la API que verifica si se está utilizando el tema oscuro y la API de cambio de tema, simplemente puede poner esto dentro de un onPressed:  
299 -  
300 -```dart  
301 -Get.changeTheme(Get.isDarkMode? ThemeData.light(): ThemeData.dark());  
302 -```  
303 -  
304 -Cuando el modo oscuro está activado, cambiará al tema claro, y cuando el tema claro esté activado, cambiará a oscuro.  
305 -  
306 -Si quieres saber en profundidad cómo cambiar el tema, puedes seguir este tutorial en Medium que incluso enseña la persistencia del tema usando GetX:  
307 -  
308 -- [Temas dinámicos en 3 líneas usando GetX](https://medium.com/swlh/flutter-dynamic-themes-in-3-lines-c3b375f292e3) - Tutorial de [Rod Brown](https://github.com/RodBr).  
309 -  
310 -## Otras API avanzadas y configuraciones manuales  
311 -  
312 -GetMaterialApp configura todo para usted, pero si desea configurar GetX manualmente utilizando APIs avanzadas.  
313 -  
314 -```dart  
315 -MaterialApp(  
316 - navigatorKey: Get.key,  
317 - navigatorObservers: [GetObserver()],  
318 -);  
319 -```  
320 -  
321 -También podrá usar su propio Middleware dentro de GetObserver, esto no influirá en nada.  
322 -  
323 -```dart  
324 -MaterialApp(  
325 - navigatorKey: Get.key,  
326 - navigatorObservers: [GetObserver(MiddleWare.observer)], // Here  
327 -);  
328 -```  
329 -  
330 -```dart  
331 -// dar los argumentos actuales de currentScreen  
332 -Get.arguments  
333 -  
334 -// dar argumentos de la ruta anterior  
335 -Get.previousArguments  
336 -  
337 -// dar el nombre de la ruta anterior  
338 -Get.previousRoute  
339 -  
340 -// dar la ruta sin procesar para acceder, por ejemplo, rawRoute.isFirst()  
341 -Get.rawRoute  
342 -  
343 -// dar acceso a Routing API desde GetObserver  
344 -Get.routing  
345 -  
346 -// comprobar si la cafetería está abierta  
347 -Get.isSnackbarOpen  
348 -  
349 -// comprobar si el diálogo está abierto  
350 -Get.isDialogOpen  
351 -  
352 -// comprobar si bottomsheet está abierto  
353 -Get.isBottomSheetOpen  
354 -  
355 -// eliminar una ruta.  
356 -Get.removeRoute()  
357 -  
358 -// volver repetidamente hasta que predicate devuelva verdadero.  
359 -Get.until()  
360 -  
361 -//ir a la siguiente ruta y eliminar todas las rutas anteriores hasta que predicate devuelva verdadero.  
362 -Get.offUntil()  
363 -  
364 -// ir a la siguiente ruta con nombre y eliminar todas las rutas anteriores hasta que predicate devuelve verdadero.  
365 -Get.offNamedUntil()  
366 -  
367 -//Verifique en qué plataforma se ejecuta la aplicación  
368 -GetPlatform.isAndroid  
369 -GetPlatform.isIOS  
370 -GetPlatform.isWeb  
371 -  
372 -// Equivalente al método: MediaQuery.of(context).size.height, pero son inmutables.  
373 -Get.height  
374 -Get.width  
375 -  
376 -// Da el contexto de la pantalla en primer plano en cualquier parte de su código.  
377 -Get.context  
378 -  
379 -// Da el contexto de la barra de bocadillos / diálogo / hoja inferior en primer plano en cualquier parte de su código.  
380 -Get.contextOverlay  
381 -  
382 -// Note: los siguientes métodos son extensiones de context. Desde que tu  
383 -// tiene acceso al contexto en cualquier lugar de su interfaz de usuario, puede usarlo en cualquier lugar del código de la interfaz de usuario  
384 -  
385 -// Si necesita un cambiable height/width (como las ventanas del navegador que se pueden escalar) necesitará usar context.  
386 -context.width  
387 -context.height  
388 -  
389 -  
390 -  
391 -// le da el poder de definir la mitad de la pantalla ahora, un tercio y así sucesivamente.  
392 -// Útil para aplicaciones receptivas.  
393 -// param dividedBy (double) optional - default: 1  
394 -// param reducedBy (double) optional - default: 0  
395 -context.heightTransformer()  
396 -context.widthTransformer()  
397 -  
398 -/// Similar a MediaQuery.of(context).size  
399 -context.mediaQuerySize()  
400 -  
401 -/// similar a MediaQuery.of(context).padding  
402 -context.mediaQueryPadding()  
403 -  
404 -/// similar a MediaQuery.of(context).viewPadding  
405 -context.mediaQueryViewPadding()  
406 -  
407 -/// similar a MediaQuery.of(context).viewInsets;  
408 -context.mediaQueryViewInsets()  
409 -  
410 -/// similar a MediaQuery.of(context).orientation;  
411 -context.orientation()  
412 -  
413 -/// comprobar si el dispositivo esta en landscape mode  
414 -context.isLandscape()  
415 -  
416 -/// comprobar si el dispositivo esta en portrait mode  
417 -context.isPortrait()  
418 -  
419 -/// similar a MediaQuery.of(context).devicePixelRatio;  
420 -context.devicePixelRatio()  
421 -  
422 -/// similar a MediaQuery.of(context).textScaleFactor;  
423 -context.textScaleFactor()  
424 -  
425 -/// obtener el lado más corto de la pantalla  
426 -context.mediaQueryShortestSide()  
427 -  
428 -/// Verdadero si el ancho es mayor que 800  
429 -context.showNavbar()  
430 -  
431 -/// Verdadero si el lado más corto es menor que 600p  
432 -context.isPhone()  
433 -  
434 -/// Verdadero si el lado más corto es más grande que 600p  
435 -context.isSmallTablet()  
436 -  
437 -/// Verdadero si el lado más corto es mayor que 720p  
438 -context.isLargeTablet()  
439 -  
440 -/// Verdadero si el dispositivo actual es una tableta  
441 -context.isTablet()  
442 -```  
443 -  
444 -### Configuraciones globales opcionales  
445 -  
446 -Puede crear configuraciones globales para GetX. Simplemente agregue Get.config a su código antes de insertar cualquier ruta o hágalo directamente en su GetMaterialApp  
447 -  
448 -```dart  
449 -GetMaterialApp(  
450 - enableLog: true,  
451 - defaultTransition: Transition.fade,  
452 - opaqueRoute: Get.isOpaqueRouteDefault,  
453 - popGesture: Get.isPopGestureEnable,  
454 - transitionDuration: Get.defaultDurationTransition,  
455 - defaultGlobalState: Get.defaultGlobalState,  
456 -);  
457 -  
458 -Get.config(  
459 - enableLog = true,  
460 - defaultPopGesture = true,  
461 - defaultTransition = Transitions.cupertino  
462 -)  
463 -```  
464 -  
465 -Opcionalmente, puede redirigir todos los mensajes de registro de Get. Si desea utilizar su propio paquete de registro favorito y desea capturar los registros allí.  
466 -  
467 -```dart  
468 -GetMaterialApp(  
469 - enableLog: true,  
470 - logWriterCallback: localLogWriter,  
471 -);  
472 -  
473 -void localLogWriter(String text, {bool isError = false}) {  
474 - // pase el mensaje a su paquete de registro favorito aquí  
475 - //Nota: incluso si los mensajes de registro están desactivados  
476 - // con el comando "enableLog: false", los mensajes seguirán pasando por aquí  
477 - // Debe verificar esta configuración manualmente aquí si desea respetarla  
478 -}  
479 -  
480 -```  
481 -  
482 -## Video explanation of Other GetX Features  
483 -  
484 -Amateur Coder hizo un video asombroso sobre utilidades, almacenamiento, enlaces y otras características! Link: [GetX Other Features](https://youtu.be/ttQtlX_Q0eU)  
485 -  
486 -# Rompiendo cambios desde 2.0  
487 -  
488 -1- Rx types:  
489 -  
490 -Antes: StringX ahora: RxString  
491 -  
492 -Antes: IntX ahora: RxInt  
493 -  
494 -Antes: MapX ahora: RxMap  
495 -  
496 -Antes: ListX ahora: RxList  
497 -  
498 -Antes: NumX ahora: RxNum  
499 -  
500 -Antes: RxDouble ahora: RxDouble  
501 -  
502 -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.  
503 -  
504 -2- Rutas Nombradas  
505 -  
506 -Antes:  
507 -  
508 -```dart  
509 -GetMaterialApp(  
510 - namedRoutes: {  
511 - '/': GetRoute(page: Home()),  
512 - }  
513 -)  
514 -```  
515 -  
516 -Ahora:  
517 -  
518 -```dart  
519 -GetMaterialApp(  
520 - getPages: [  
521 - GetPage(name: '/', page: () => Home()),  
522 - ]  
523 -)  
524 -```  
525 -  
526 -¿Por qué este cambio?  
527 -  
528 -A menudo, puede ser necesario decidir qué página se mostrará desde un parámetro o un token de inicio de sesión, el enfoque anterior era inflexible, ya que no permitía esto.  
529 -  
530 -Insertar la página en una función ha reducido significativamente el consumo de RAM, ya que las rutas no se asignarán en la memoria desde que se inició la aplicación, y también permitió hacer este tipo de enfoque:  
531 -  
532 -```dart  
533 -GetStorage box = GetStorage();  
534 -  
535 -GetMaterialApp(  
536 - getPages: [  
537 - GetPage(name: '/', page:(){  
538 - return box.hasData('token') ? Home() : Login();  
539 - })  
540 - ]  
541 -)  
542 -```  
543 -  
544 -# ¿Por qué Getx?  
545 -  
546 -1- Después de una actualización de Flutter, muchos paquetes suelen romperse. A veces se producen errores de compilación, errores de los que aún no hay respuestas y el desarrollador necesita saber el origen del error, poder rastrear, y solo entonces intentar abrir un issue en el repositorio correspondiente, para finalmente ver su problema resuelto. Getx centraliza los principales recursos para el desarrollo (gestión de estado, dependencia y rutas), lo que le permite agregar un único paquete a su pubspec y comenzar a trabajar. Después de una actualización de Flutter, lo único que debe hacer es actualizar la dependencia Get y ponerse a trabajar. Get también resuelve problemas de compatibilidad. ¿Cuántas veces una versión de un paquete no es compatible con la versión de otro, porque una usa una dependencia en una versión y la otra en otra? Tampoco es una preocupación usando Get, ya que todo estará en el mismo paquete y será totalmente compatible.  
547 -  
548 -2- Flutter es fácil, Flutter es increíble, pero todavía tiene algo repetitivo que puede ser no deseado para la mayoría de los desarrolladores, como `Navigator.of(context).push (context, builder [...]`. Get simplifica el desarrollo. En lugar de escribir 8 líneas de código para simplemente llamar a una ruta, simplemente puede hacerlo: `Get.to(Home())` y listo, irá a la página siguiente. Algo doloroso de hacer con Flutter actualmente, mientras que con GetX es estúpidamente simple. Gestionar estados en Flutter y dependencias también es algo que genera mucho debate, ya que hay cientos de patrones en el pub. Pero no hay nada tan fácil como agregar un ".obs" al final de su variable, y colocar su widget dentro de un Obx, y eso es todo, todas las actualizaciones de esa variable se actualizarán automáticamente en la pantalla.  
549 -  
550 -3- Facilidad sin preocuparse por el rendimiento. El rendimiento de Flutter ya es sorprendente, pero imagine que usa un gestor de estado y un localizador para distribuir sus clases de bloc/stores/controllers/ etc. Tendrá que llamar manualmente a la exclusión de esa dependencia cuando no la necesite. Pero, ¿alguna vez pensó en simplemente usar el controlador, y cuando ya no sea necesario, simplemente se elimine de la memoria? Eso es lo que hace GetX. Con SmartManagement, todo lo que no se está utilizando se elimina de la memoria, y no debería tener que preocuparse por nada más que la programación. Se le garantiza el consumo mínimo de recursos, sin siquiera haber creado una lógica para esto.  
551 -  
552 -4- Desacoplamiento real. Es posible que haya escuchado la idea de "separar la vista de la lógica de negocio". Esta no es una peculiaridad de BLoC, MVC, MVVM, cualquier otro estándar en el mercado tiene este concepto. Sin embargo, a menudo se puede mitigar en Flutter debido al uso del contexto.  
553 -Si necesita contexto para encontrar un InheritedWidget, lo necesita en la vista o pasado por parámetro. En particular, encuentro esta solución muy fea, y para trabajar en equipo siempre tendremos una dependencia de la lógica de negocios de la vista. Getx no es ortodoxo con el enfoque estándar, y aunque no prohíbe completamente el uso de StatefulWidgets, InitState, etc., siempre tiene un enfoque similar que puede ser más limpio. Los controladores tienen ciclos de vida, y cuando necesita hacer una solicitud API REST, por ejemplo, no depende de nada en la vista. Puede usar onInit para iniciar la llamada http, y cuando lleguen los datos, se rellenarán las variables. Como GetX es completamente reactivo (realmente, y funciona bajo streams), una vez que se llenan los elementos, todos los widgets que usan esa variable se actualizarán automáticamente en la vista. Esto permite que las personas con experiencia en IU trabajen solo con widgets y no tengan que enviar nada a la lógica de negocios que no sean eventos de usuario (como hacer clic en un botón), mientras que las personas que trabajan con lógica de negocios podrán crearla y probarla por separado.  
554 -  
555 -Esta librería siempre se actualizará e implementará nuevas características. Siéntase libre de ofrecer PRs y contribuir a ellas.  
1 -![](get.png)  
2 -  
3 -_Languages: English (this file), [Brazilian Portuguese](README.pt-br.md), [Spanish](README-es.md),[Polish](README.pl.md)._  
4 -  
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)  
7 -[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart)  
8 -[![Discord Shield](https://img.shields.io/discord/722900883784073290.svg?logo=discord)](https://discord.com/invite/9Hpt99N)  
9 -[![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](https://communityinviter.com/apps/getxworkspace/getx)  
10 -[![Telegram](https://img.shields.io/badge/chat-on%20Telegram-blue.svg)](https://t.me/joinchat/PhdbJRmsZNpAqSLJL6bH7g)  
11 -<a href="https://github.com/Solido/awesome-flutter">  
12 -<img alt="Awesome Flutter" src="https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square" />  
13 -</a>  
14 -<a href="https://www.buymeacoffee.com/jonataslaw" target="_blank"><img src="https://i.imgur.com/aV6DDA7.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" > </a>  
15 -  
16 -![](getx.png)  
17 -  
18 -- [About Get](#about-get)  
19 -- [Installing](#installing)  
20 -- [Counter App with GetX](#counter-app-with-getx)  
21 -- [The Three pillars](#the-three-pillars)  
22 - - [State management](#state-management)  
23 - - [Reactive State Manager](#reactive-state-manager)  
24 - - [More details about state management](#more-details-about-state-management)  
25 - - [Route management](#route-management)  
26 - - [More details about route management](#more-details-about-route-management)  
27 - - [Dependency management](#dependency-management)  
28 - - [More details about dependency management](#more-details-about-dependency-management)  
29 -- [Utils](#utils)  
30 - - [Internationalization](#internationalization)  
31 - - [Translations](#translations)  
32 - - [Using translations](#using-translations)  
33 - - [Locales](#locales)  
34 - - [Change locale](#change-locale)  
35 - - [System locale](#system-locale)  
36 - - [Change Theme](#change-theme)  
37 - - [Other Advanced APIs](#other-advanced-apis)  
38 - - [Optional Global Settings and Manual configurations](#optional-global-settings-and-manual-configurations)  
39 - - [Local State Widgets](#local-state-widgets)  
40 - - [ValueBuilder](#valuebuilder)  
41 - - [ObxValue](#obxvalue)  
42 - - [Useful tips](#useful-tips)  
43 - - [GetView](#getview)  
44 - - [GetWidget](#getwidget)  
45 - - [GetxService](#getxservice)  
46 -- [Breaking changes from 2.0](#breaking-changes-from-20)  
47 -- [Why Getx?](#why-getx)  
48 -- [Community](#community)  
49 - - [Community channels](#community-channels)  
50 - - [How to contribute](#how-to-contribute)  
51 - - [Articles and videos](#articles-and-videos)  
52 -  
53 -# About Get  
54 -  
55 -- GetX is an extra-light and powerful solution for Flutter. It combines high performance state management, intelligent dependency injection, and route management in a quick and practical way.  
56 -  
57 -- GetX has 3 basic principles, this means that this is the priority for all resources in the library  
58 -  
59 - - **PERFORMANCE:** GetX is focused on performance and minimum consumption of resources. Benchmarks are almost always not important in the real world, but if you want, there is a consumption indicator here([benchmarks](https://github.com/jonataslaw/benchmarks)), where GetX does better than other state management approaches, for example. The difference is not large, but it shows our concern not to waste its resources.  
60 - - **PRODUCTIVITY:** GetX uses an easy and pleasant syntax. No matter what you want to do, there is always an easier way with Getx. It will save hours of development, and will extract the maximum performance that your application can deliver  
61 - - **ORGANIZATION:** GetX allows the total decoupling of the View, presentation logic, business logic, dependency injection, and navigation. You do not need context to navigate between routes, so you are not dependent on the widget tree (visualization) for this. You don't need context to access your controllers / blocks through an inheritedWidget, so you completely decouple your presentation logic and business logic from your visualization layer. You do not need to inject your Controllers/Models/Blocs classes into your widget tree through multiproviders, for this GetX uses its own dependency injection feature, decoupling the DI from its view completely.  
62 - With GetX you know where to find each feature of your application, having clean code by default. This in addition to facilitating maintenance, makes the sharing of modules, something that until then in Flutter was unthinkable, something totally possible.  
63 - BLoC was a starting point for organizing code in Flutter, it separates business logic from visualization. Getx is a natural evolution of this, not only separating the business logic, but the presentation logic. Bonus injection of dependencies and routes are also decoupled, and the data layer is out of it all. You know where everything is, and all of this in an easier way than building a hello world.  
64 - GetX is the easiest, most practical and scalable way to build high-performance applications with the Flutter SDK, with a large ecosystem around it that works perfectly together, being easy for beginners, and accurate for experts. It is secure, stable, up-to-date, and offers a huge range of APIs build-in that are not present on default Flutter SDK.  
65 -  
66 -- GetX is not a bloated. It has a multitude of features that allow you to start programming without worrying about anything, but each of these features are in separate containers, and are only started after use. If you only use State Management, only State Management will be compiled. If you only use routes, nothing from the state management will be compiled. You can compile the benchmark repository, and you will see that using only Get state management, the application compiled with Get has become smaller than all other applications that have only the state management of other packages, because nothing that is not used will be compiled into your code, and each GetX solution was designed to be extra lightweight. The merit here also comes from Flutter's tree shaking which is incredible, and manages to eliminate unused resources like no other framework does.  
67 -  
68 -- Getx has a huge ecosystem, capable of running with the same code on Android, iOS, Web, Mac, Linux, Windows, and on your server.  
69 -**It is possible to fully reuse your code made on the frontend on your backend with [Get Server](https://github.com/jonataslaw/get_server)**.  
70 -  
71 -**In addition, the entire development process can be completely automated, both on the server and on the front end with [Get CLI](https://github.com/jonataslaw/get_cli)**.  
72 -  
73 -**In addition, to further increase your productivity, we have the  
74 -[extension to VSCode](https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets) and the [extension to Android Studio/Intellij](https://plugins.jetbrains.com/plugin/14975-getx-snippets)**  
75 -  
76 -# Installing  
77 -  
78 -Add Get to your pubspec.yaml file:  
79 -  
80 -```yaml  
81 -dependencies:  
82 - get:  
83 -```  
84 -  
85 -Import get in files that it will be used:  
86 -  
87 -```dart  
88 -import 'package:get/get.dart';  
89 -```  
90 -  
91 -# Counter App with GetX  
92 -  
93 -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.  
94 -  
95 -- Step 1:  
96 - Add "Get" before your MaterialApp, turning it into GetMaterialApp  
97 -  
98 -```dart  
99 -void main() => runApp(GetMaterialApp(home: Home()));  
100 -```  
101 -  
102 -- Note: this does not modify the MaterialApp of the Flutter, GetMaterialApp is not a modified MaterialApp, it is just a pre-configured Widget, which has the default MaterialApp as a child. You can configure this manually, but it is definitely not necessary. GetMaterialApp will create routes, inject them, inject translations, inject everything you need for route navigation. If you use Get only for state management or dependency management, it is not necessary to use GetMaterialApp. GetMaterialApp is necessary for routes, snackbars, internationalization, bottomSheets, dialogs, and high-level apis related to routes and absence of context.  
103 -- Note²: This step in only necessary if you gonna use route management (`Get.to()`, `Get.back()` and so on). If you not gonna use it then it is not necessary to do step 1  
104 -  
105 -- Step 2:  
106 - Create your business logic class and place all variables, methods and controllers inside it.  
107 - You can make any variable observable using a simple ".obs".  
108 -  
109 -```dart  
110 -class Controller extends GetxController{  
111 - var count = 0.obs;  
112 - increment() => count++;  
113 -}  
114 -```  
115 -  
116 -- Step 3:  
117 - Create your View, use StatelessWidget and save some RAM, with Get you may no longer need to use StatefulWidget.  
118 -  
119 -```dart  
120 -class Home extends StatelessWidget {  
121 -  
122 - // Instantiate your class using Get.put() to make it available for all "child" routes there.  
123 - final Controller c = Get.put(Controller());  
124 -  
125 - @override  
126 - Widget build(context) => Scaffold(  
127 - // Use Obx(()=> to update Text() whenever count is changed.  
128 - appBar: AppBar(title: Obx(() => Text("Clicks: ${c.count}"))),  
129 -  
130 - // Replace the 8 lines Navigator.push by a simple Get.to(). You don't need context  
131 - body: Center(child: RaisedButton(  
132 - child: Text("Go to Other"), onPressed: () => Get.to(Other()))),  
133 - floatingActionButton:  
134 - FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment));  
135 -}  
136 -  
137 -class Other extends StatelessWidget {  
138 - // You can ask Get to find a Controller that is being used by another page and redirect you to it.  
139 - final Controller c = Get.find();  
140 -  
141 - @override  
142 - Widget build(context){  
143 - // Access the updated count variable  
144 - return Scaffold(body: Center(child: Text("${c.count}")));  
145 - }  
146 -}  
147 -```  
148 -  
149 -Result:  
150 -  
151 -![](counter-app-gif.gif)  
152 -  
153 -This is a simple project but it already makes clear how powerful Get is. As your project grows, this difference will become more significant.  
154 -  
155 -Get was designed to work with teams, but it makes the job of an individual developer simple.  
156 -  
157 -Improve your deadlines, deliver everything on time without losing performance. Get is not for everyone, but if you identified with that phrase, Get is for you!  
158 -  
159 -# The Three pillars  
160 -  
161 -## State management  
162 -  
163 -There are currently several state managers for Flutter. However, most of them involve using ChangeNotifier to update widgets and this is a bad and very bad approach to performance of medium or large applications. You can check in the official Flutter documentation that [ChangeNotifier should be used with 1 or a maximum of 2 listeners](https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html), making it practically unusable for any application medium or large.  
164 -  
165 -Get isn't better or worse than any other state manager, but that you should analyze these points as well as the points below to choose between using Get in pure form (Vanilla), or using it in conjunction with another state manager.  
166 -  
167 -Definitely, Get is not the enemy of any other state manager, because Get is a microframework, not just a state manager, and can be used either alone or in conjunction with them.  
168 -  
169 -Get has two different state managers: the simple state manager (we'll call it GetBuilder) and the reactive state manager (who has the package name, GetX)  
170 -  
171 -### Reactive State Manager  
172 -  
173 -Reactive programming can alienate many people because it is said to be complicated. GetX turns reactive programming into something quite simple:  
174 -  
175 -- You won't need to create StreamControllers.  
176 -- You won't need to create a StreamBuilder for each variable  
177 -- You will not need to create a class for each state.  
178 -- You will not need to create a get for an initial value.  
179 -  
180 -Reactive programming with Get is as easy as using setState.  
181 -  
182 -Let's imagine that you have a name variable and want that every time you change it, all widgets that use it are automatically changed.  
183 -  
184 -This is your count variable:  
185 -  
186 -```dart  
187 -var name = 'Jonatas Borges';  
188 -```  
189 -  
190 -To make it observable, you just need to add ".obs" to the end of it:  
191 -  
192 -```dart  
193 -var name = 'Jonatas Borges'.obs;  
194 -```  
195 -  
196 -And in the UI, when you want to show that value and update the screen whenever tha values changes, simply do this:  
197 -  
198 -```dart  
199 -Obx(() => Text("${controller.name}"));  
200 -```  
201 -  
202 -That's all. It's _that_ simple.  
203 -  
204 -### More details about state management  
205 -  
206 -**See an more in-depth explanation of state management [here](./documentation/en_US/state_management.md). There you will see more examples and also the difference between the simple stage manager and the reactive state manager**  
207 -  
208 -You will get a good idea of GetX power.  
209 -  
210 -## Route management  
211 -  
212 -If you are going to use routes/snackbars/dialogs/bottomsheets without context, GetX is excellent for you too, just see it:  
213 -  
214 -Add "Get" before your MaterialApp, turning it into GetMaterialApp  
215 -  
216 -```dart  
217 -GetMaterialApp( // Before: MaterialApp(  
218 - home: MyHome(),  
219 -)  
220 -```  
221 -  
222 -Navigate to new screen:  
223 -  
224 -```dart  
225 -  
226 -Get.to(NextScreen());  
227 -```  
228 -  
229 -Navigate to new screen with name. See more details on named routes [here](./documentation/en_US/route_management.md#navigation-with-named-routes)  
230 -  
231 -```dart  
232 -  
233 -Get.toNamed('/details');  
234 -```  
235 -  
236 -To close snackbars, dialogs, bottomsheets, or anything you would normally close with Navigator.pop(context);  
237 -  
238 -```dart  
239 -Get.back();  
240 -```  
241 -  
242 -To go to the next screen and no option to go back to the previous screen (for use in SplashScreens, login screens and etc.)  
243 -  
244 -```dart  
245 -Get.off(NextScreen());  
246 -```  
247 -  
248 -To go to the next screen and cancel all previous routes (useful in shopping carts, polls, and tests)  
249 -  
250 -```dart  
251 -Get.offAll(NextScreen());  
252 -```  
253 -  
254 -Noticed that you didn't had to use context to do any of these things? That's one of the biggest advantages of using Get route management. With this, you can execute all these methods from within your controller class, without worries.  
255 -  
256 -### More details about route management  
257 -  
258 -**Get work with named routes and also offer a lower level control over your routes! There is a in-depth documentation [here](./documentation/en_US/route_management.md)**  
259 -  
260 -## Dependency management  
261 -  
262 -Get has a simple and powerful dependency manager that allows you to retrieve the same class as your Bloc or Controller with just 1 lines of code, no Provider context, no inheritedWidget:  
263 -  
264 -```dart  
265 -Controller controller = Get.put(Controller()); // Rather Controller controller = Controller();  
266 -```  
267 -  
268 -- Note: If you are using Get's State Manager, pay more attention to the bindings api, which will make easier to connect your view to your controller.  
269 -  
270 -Instead of instantiating your class within the class you are using, you are instantiating it within the Get instance, which will make it available throughout your App.  
271 -So you can use your controller (or class Bloc) normally  
272 -  
273 -**Tip:** Get dependency management is decloupled from other parts of the package, so if for example your app is already using a state manager (any one, it doesn't matter), you don't need to rewrite it all, you can use this dependency injection with no problems at all  
274 -  
275 -```dart  
276 -controller.fetchApi();  
277 -```  
278 -  
279 -Imagine that you have navigated through numerous routes, and you need a data that was left behind in your controller, you would need a state manager combined with the Provider or Get_it, correct? Not with Get. You just need to ask Get to "find" for your controller, you don't need any additional dependencies:  
280 -  
281 -```dart  
282 -Controller controller = Get.find();  
283 -//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.  
284 -```  
285 -  
286 -And then you will be able to recover your controller data that was obtained back there:  
287 -  
288 -```dart  
289 -Text(controller.textFromApi);  
290 -```  
291 -  
292 -### More details about dependency management  
293 -  
294 -**See a more in-depth explanation of dependency management [here](./documentation/en_US/dependency_management.md)**  
295 -  
296 -# Utils  
297 -  
298 -## Internationalization  
299 -  
300 -### Translations  
301 -  
302 -Translations are kept as a simple key-value dictionary map.  
303 -To add custom translations, create a class and extend `Translations`.  
304 -  
305 -```dart  
306 -import 'package:get/get.dart';  
307 -  
308 -class Messages extends Translations {  
309 - @override  
310 - Map<String, Map<String, String>> get keys => {  
311 - 'en_US': {  
312 - 'hello': 'Hello World',  
313 - },  
314 - 'de_DE': {  
315 - 'hello': 'Hallo Welt',  
316 - }  
317 - };  
318 -}  
319 -```  
320 -  
321 -#### Using translations  
322 -  
323 -Just append `.tr` to the specified key and it will be translated, using the current value of `Get.locale` and `Get.fallbackLocale`.  
324 -  
325 -```dart  
326 -Text('title'.tr);  
327 -```  
328 -  
329 -### Locales  
330 -  
331 -Pass parameters to `GetMaterialApp` to define the locale and translations.  
332 -  
333 -```dart  
334 -return GetMaterialApp(  
335 - translations: Messages(), // your translations  
336 - locale: Locale('en', 'US'), // translations will be displayed in that locale  
337 - fallbackLocale: Locale('en', 'UK'), // specify the fallback locale in case an invalid locale is selected.  
338 -);  
339 -```  
340 -  
341 -#### Change locale  
342 -  
343 -Call `Get.updateLocale(locale)` to update the locale. Translations then automatically use the new locale.  
344 -  
345 -```dart  
346 -var locale = Locale('en', 'US');  
347 -Get.updateLocale(locale);  
348 -```  
349 -  
350 -#### System locale  
351 -  
352 -To read the system locale, you could use `window.locale`.  
353 -  
354 -```dart  
355 -import 'dart:ui' as ui;  
356 -  
357 -return GetMaterialApp(  
358 - locale: ui.window.locale,  
359 -);  
360 -```  
361 -  
362 -## Change Theme  
363 -  
364 -Please do not use any higher level widget than `GetMaterialApp` in order to update it. This can trigger duplicate keys. A lot of people are used to the prehistoric approach of creating a "ThemeProvider" widget just to change the theme of your app, and this is definitely NOT necessary with **GetX™**.  
365 -  
366 -You can create your custom theme and simply add it within `Get.changeTheme` without any boilerplate for that:  
367 -  
368 -```dart  
369 -Get.changeTheme(ThemeData.light());  
370 -```  
371 -  
372 -If you want to create something like a button that changes the Theme in `onTap`, you can combine two **GetX™** APIs for that:  
373 -  
374 -- The api that checks if the dark `Theme` is being used.  
375 -- And the `Theme` Change API, you can just put this within an `onPressed`:  
376 -  
377 -```dart  
378 -Get.changeTheme(Get.isDarkMode? ThemeData.light(): ThemeData.dark());  
379 -```  
380 -  
381 -When `.darkmode` is activated, it will switch to the _light theme_, and when the _light theme_ becomes active, it will change to _dark theme_.  
382 -  
383 -## Other Advanced APIs  
384 -  
385 -```dart  
386 -// give the current args from currentScreen  
387 -Get.arguments  
388 -  
389 -// give arguments of previous route  
390 -Get.previousArguments  
391 -  
392 -// give name of previous route  
393 -Get.previousRoute  
394 -  
395 -// give the raw route to access for example, rawRoute.isFirst()  
396 -Get.rawRoute  
397 -  
398 -// give access to Rounting API from GetObserver  
399 -Get.routing  
400 -  
401 -// check if snackbar is open  
402 -Get.isSnackbarOpen  
403 -  
404 -// check if dialog is open  
405 -Get.isDialogOpen  
406 -  
407 -// check if bottomsheet is open  
408 -Get.isBottomSheetOpen  
409 -  
410 -// remove one route.  
411 -Get.removeRoute()  
412 -  
413 -// back repeatedly until the predicate returns true.  
414 -Get.until()  
415 -  
416 -// go to next route and remove all the previous routes until the predicate returns true.  
417 -Get.offUntil()  
418 -  
419 -// go to next named route and remove all the previous routes until the predicate returns true.  
420 -Get.offNamedUntil()  
421 -  
422 -//Check in what platform the app is running  
423 -GetPlatform.isAndroid  
424 -GetPlatform.isIOS  
425 -GetPlatform.isMacOS  
426 -GetPlatform.isWindows  
427 -GetPlatform.isLinux  
428 -GetPlatform.isFuchsia  
429 -  
430 -//Check the device type  
431 -GetPlatform.isMobile  
432 -GetPlatform.isDesktop  
433 -//All platforms are supported independently in web!  
434 -//You can tell if you are running inside a browser  
435 -//on Windows, iOS, OSX, Android, etc.  
436 -GetPlatform.isWeb  
437 -  
438 -  
439 -// Equivalent to : MediaQuery.of(context).size.height,  
440 -// but immutable.  
441 -Get.height  
442 -Get.width  
443 -  
444 -// Gives the current context of the Navigator.  
445 -Get.context  
446 -  
447 -// Gives the context of the snackbar/dialog/bottomsheet in the foreground, anywhere in your code.  
448 -Get.contextOverlay  
449 -  
450 -// Note: the following methods are extensions on context. Since you  
451 -// have access to context in any place of your UI, you can use it anywhere in the UI code  
452 -  
453 -// If you need a changeable height/width (like Desktop or browser windows that can be scaled) you will need to use context.  
454 -context.width  
455 -context.height  
456 -  
457 -// Gives you the power to define half the screen, a third of it and so on.  
458 -// Useful for responsive applications.  
459 -// param dividedBy (double) optional - default: 1  
460 -// param reducedBy (double) optional - default: 0  
461 -context.heightTransformer()  
462 -context.widthTransformer()  
463 -  
464 -/// Similar to MediaQuery.of(context).size  
465 -context.mediaQuerySize()  
466 -  
467 -/// Similar to MediaQuery.of(context).padding  
468 -context.mediaQueryPadding()  
469 -  
470 -/// Similar to MediaQuery.of(context).viewPadding  
471 -context.mediaQueryViewPadding()  
472 -  
473 -/// Similar to MediaQuery.of(context).viewInsets;  
474 -context.mediaQueryViewInsets()  
475 -  
476 -/// Similar to MediaQuery.of(context).orientation;  
477 -context.orientation()  
478 -  
479 -/// Check if device is on landscape mode  
480 -context.isLandscape()  
481 -  
482 -/// Check if device is on portrait mode  
483 -context.isPortrait()  
484 -  
485 -/// Similar to MediaQuery.of(context).devicePixelRatio;  
486 -context.devicePixelRatio()  
487 -  
488 -/// Similar to MediaQuery.of(context).textScaleFactor;  
489 -context.textScaleFactor()  
490 -  
491 -/// Get the shortestSide from screen  
492 -context.mediaQueryShortestSide()  
493 -  
494 -/// True if width be larger than 800  
495 -context.showNavbar()  
496 -  
497 -/// True if the shortestSide is smaller than 600p  
498 -context.isPhone()  
499 -  
500 -/// True if the shortestSide is largest than 600p  
501 -context.isSmallTablet()  
502 -  
503 -/// True if the shortestSide is largest than 720p  
504 -context.isLargeTablet()  
505 -  
506 -/// True if the current device is Tablet  
507 -context.isTablet()  
508 -  
509 -/// Returns a value<T> according to the screen size  
510 -/// can give value for:  
511 -/// watch: if the shortestSide is smaller than 300  
512 -/// mobile: if the shortestSide is smaller than 600  
513 -/// tablet: if the shortestSide is smaller than 1200  
514 -/// desktop: if width is largest than 1200  
515 -context.responsiveValue<T>()  
516 -```  
517 -  
518 -### Optional Global Settings and Manual configurations  
519 -  
520 -GetMaterialApp configures everything for you, but if you want to configure Get manually.  
521 -  
522 -```dart  
523 -MaterialApp(  
524 - navigatorKey: Get.key,  
525 - navigatorObservers: [GetObserver()],  
526 -);  
527 -```  
528 -  
529 -You will also be able to use your own Middleware within `GetObserver`, this will not influence anything.  
530 -  
531 -```dart  
532 -MaterialApp(  
533 - navigatorKey: Get.key,  
534 - navigatorObservers: [  
535 - GetObserver(MiddleWare.observer) // Here  
536 - ],  
537 -);  
538 -```  
539 -  
540 -You can create _Global Settings_ for `Get`. Just add `Get.config` to your code before pushing any route.  
541 -Or do it directly in your `GetMaterialApp`  
542 -  
543 -```dart  
544 -GetMaterialApp(  
545 - enableLog: true,  
546 - defaultTransition: Transition.fade,  
547 - opaqueRoute: Get.isOpaqueRouteDefault,  
548 - popGesture: Get.isPopGestureEnable,  
549 - transitionDuration: Get.defaultDurationTransition,  
550 - defaultGlobalState: Get.defaultGlobalState,  
551 -);  
552 -  
553 -Get.config(  
554 - enableLog = true,  
555 - defaultPopGesture = true,  
556 - defaultTransition = Transitions.cupertino  
557 -)  
558 -```  
559 -  
560 -You can optionally redirect all the logging messages from `Get`.  
561 -If you want to use your own, favourite logging package,  
562 -and want to capture the logs there:  
563 -  
564 -```dart  
565 -GetMaterialApp(  
566 - enableLog: true,  
567 - logWriterCallback: localLogWriter,  
568 -);  
569 -  
570 -void localLogWriter(String text, {bool isError = false}) {  
571 - // pass the message to your favourite logging package here  
572 - // please note that even if enableLog: false log messages will be pushed in this callback  
573 - // you get check the flag if you want through GetConfig.isLogEnable  
574 -}  
575 -  
576 -```  
577 -  
578 -### Local State Widgets  
579 -  
580 -These Widgets allows you to manage a single value, and keep the state ephemeral and locally.  
581 -We have flavours for Reactive and Simple.  
582 -For instance, you might use them to toggle obscureText in a `TextField`, maybe create a custom  
583 -Expandable Panel, or maybe modify the current index in `BottomNavigationBar` while changing the content  
584 -of the body in a `Scaffold`.  
585 -  
586 -#### ValueBuilder  
587 -  
588 -A simplification of `StatefulWidget` that works with a `.setState` callback that takes the updated value.  
589 -  
590 -```dart  
591 -ValueBuilder<bool>(  
592 - initialValue: false,  
593 - builder: (value, updateFn) => Switch(  
594 - value: value,  
595 - onChanged: updateFn, // same signature! you could use ( newValue ) => updateFn( newValue )  
596 - ),  
597 - // if you need to call something outside the builder method.  
598 - onUpdate: (value) => print("Value updated: $value"),  
599 - onDispose: () => print("Widget unmounted"),  
600 -),  
601 -```  
602 -  
603 -#### ObxValue  
604 -  
605 -Similar to [`ValueBuilder`](#valuebuilder), but this is the Reactive version, you pass a Rx instance (remember the magical .obs?) and  
606 -updates automatically... isn't it awesome?  
607 -  
608 -```dart  
609 -ObxValue((data) => Switch(  
610 - value: data.value,  
611 - onChanged: data, // Rx has a _callable_ function! You could use (flag) => data.value = flag,  
612 - ),  
613 - false.obs,  
614 -),  
615 -```  
616 -  
617 -## Useful tips  
618 -  
619 -`.obs`ervables (also known as _Rx_ Types) have a wide variety of internal methods and operators.  
620 -  
621 -> Is very common to _believe_ that a property with `.obs` **IS** the actual value... but make no mistake!  
622 -> We avoid the Type declaration of the variable, because Dart's compiler is smart enough, and the code  
623 -> looks cleaner, but:  
624 -  
625 -```dart  
626 -var message = 'Hello world'.obs;  
627 -print( 'Message "$message" has Type ${message.runtimeType}');  
628 -```  
629 -  
630 -Even if `message` _prints_ the actual String value, the Type is **RxString**!  
631 -  
632 -So, you can't do `message.substring( 0, 4 )`.  
633 -You have to access the real `value` inside the _observable_:  
634 -The most "used way" is `.value`, but, did you know that you can also use...  
635 -  
636 -```dart  
637 -final name = 'GetX'.obs;  
638 -// only "updates" the stream, if the value is different from the current one.  
639 -name.value = 'Hey';  
640 -  
641 -// All Rx properties are "callable" and returns the new value.  
642 -// but this approach does not accepts `null`, the UI will not rebuild.  
643 -name('Hello');  
644 -  
645 -// is like a getter, prints 'Hello'.  
646 -name() ;  
647 -  
648 -/// numbers:  
649 -  
650 -final count = 0.obs;  
651 -  
652 -// You can use all non mutable operations from num primitives!  
653 -count + 1;  
654 -  
655 -// Watch out! this is only valid if `count` is not final, but var  
656 -count += 1;  
657 -  
658 -// You can also compare against values:  
659 -count > 2;  
660 -  
661 -/// booleans:  
662 -  
663 -final flag = false.obs;  
664 -  
665 -// switches the value between true/false  
666 -flag.toggle();  
667 -  
668 -  
669 -/// all types:  
670 -  
671 -// Sets the `value` to null.  
672 -flag.nil();  
673 -  
674 -// All toString(), toJson() operations are passed down to the `value`  
675 -print( count ); // calls `toString()` inside for RxInt  
676 -  
677 -final abc = [0,1,2].obs;  
678 -// Converts the value to a json Array, prints RxList  
679 -// Json is supported by all Rx types!  
680 -print('json: ${jsonEncode(abc)}, type: ${abc.runtimeType}');  
681 -  
682 -// RxMap, RxList and RxSet are special Rx types, that extends their native types.  
683 -// but you can work with a List as a regular list, although is reactive!  
684 -abc.add(12); // pushes 12 to the list, and UPDATES the stream.  
685 -abc[3]; // like Lists, reads the index 3.  
686 -  
687 -  
688 -// equality works with the Rx and the value, but hashCode is always taken from the value  
689 -final number = 12.obs;  
690 -print( number == 12 ); // prints > true  
691 -  
692 -/// Custom Rx Models:  
693 -  
694 -// toJson(), toString() are deferred to the child, so you can implement override on them, and print() the observable directly.  
695 -  
696 -class User {  
697 - String name, last;  
698 - int age;  
699 - User({this.name, this.last, this.age});  
700 -  
701 - @override  
702 - String toString() => '$name $last, $age years old';  
703 -}  
704 -  
705 -final user = User(name: 'John', last: 'Doe', age: 33).obs;  
706 -  
707 -// `user` is "reactive", but the properties inside ARE NOT!  
708 -// So, if we change some variable inside of it...  
709 -user.value.name = 'Roi';  
710 -// The widget will not rebuild!,  
711 -// `Rx` don't have any clue when you change something inside user.  
712 -// So, for custom classes, we need to manually "notify" the change.  
713 -user.refresh();  
714 -  
715 -// or we can use the `update()` method!  
716 -user.update((value){  
717 - value.name='Roi';  
718 -});  
719 -  
720 -print( user );  
721 -```  
722 -  
723 -#### GetView  
724 -  
725 -I love this Widget, is so simple, yet, so useful!  
726 -  
727 -Is a `const Stateless` Widget that has a getter `controller` for a registered `Controller`, that's all.  
728 -  
729 -```dart  
730 - class AwesomeController extends GetxController {  
731 - final String title = 'My Awesome View';  
732 - }  
733 -  
734 - // ALWAYS remember to pass the `Type` you used to register your controller!  
735 - class AwesomeView extends GetView<AwesomeController> {  
736 - @override  
737 - Widget build(BuildContext context) {  
738 - return Container(  
739 - padding: EdgeInsets.all(20),  
740 - child: Text( controller.title ), // just call `controller.something`  
741 - );  
742 - }  
743 - }  
744 -```  
745 -  
746 -#### GetWidget  
747 -  
748 -Most people have no idea about this Widget, or totally confuse the usage of it.  
749 -The use case is very rare, but very specific: It `caches` a Controller.  
750 -Because of the _cache_, can't be a `const Stateless`.  
751 -  
752 -> So, when do you need to "cache" a Controller?  
753 -  
754 -If you use, another "not so common" feature of **GetX**: `Get.create()`.  
755 -  
756 -`Get.create(()=>Controller())` will generate a new `Controller` each time you call  
757 -`Get.find<Controller>()`,  
758 -  
759 -That's where `GetWidget` shines... as you can use it, for example,  
760 -to keep a list of Todo items. So, if the widget gets "rebuilt", it will keep the same controller instance.  
761 -  
762 -#### GetxService  
763 -  
764 -This class is like a `GetxController`, it shares the same lifecycle ( `onInit()`, `onReady()`, `onClose()`).  
765 -But has no "logic" inside of it. It just notifies **GetX** Dependency Injection system, that this subclass  
766 -**can not** be removed from memory.  
767 -  
768 -So is super useful to keep your "Services" always reachable and active with `Get.find()`. Like:  
769 -`ApiService`, `StorageService`, `CacheService`.  
770 -  
771 -```dart  
772 -Future<void> main() async {  
773 - await initServices(); /// AWAIT SERVICES INITIALIZATION.  
774 - runApp(SomeApp());  
775 -}  
776 -  
777 -/// Is a smart move to make your Services intiialize before you run the Flutter app.  
778 -/// as you can control the execution flow (maybe you need to load some Theme configuration,  
779 -/// apiKey, language defined by the User... so load SettingService before running ApiService.  
780 -/// so GetMaterialApp() doesnt have to rebuild, and takes the values directly.  
781 -void initServices() async {  
782 - print('starting services ...');  
783 - /// Here is where you put get_storage, hive, shared_pref initialization.  
784 - /// or moor connection, or whatever that's async.  
785 - await Get.putAsync(() => DbService().init());  
786 - await Get.putAsync(SettingsService()).init();  
787 - print('All services started...');  
788 -}  
789 -  
790 -class DbService extends GetxService {  
791 - Future<DbService> init() async {  
792 - print('$runtimeType delays 2 sec');  
793 - await 2.delay();  
794 - print('$runtimeType ready!');  
795 - return this;  
796 - }  
797 -}  
798 -  
799 -class SettingsService extends GetxService {  
800 - void init() async {  
801 - print('$runtimeType delays 1 sec');  
802 - await 1.delay();  
803 - print('$runtimeType ready!');  
804 - }  
805 -}  
806 -  
807 -```  
808 -  
809 -The only way to actually delete a `GetxService`, is with `Get.reset()` which is like a  
810 -"Hot Reboot" of your app. So remember, if you need absolute persistance of a class instance during the  
811 -lifetime of your app, use `GetxService`.  
812 -  
813 -# Breaking changes from 2.0  
814 -  
815 -1- Rx types:  
816 -  
817 -| Before | After |  
818 -| ------- | ---------- |  
819 -| StringX | `RxString` |  
820 -| IntX | `RxInt` |  
821 -| MapX | `RxMap` |  
822 -| ListX | `RxList` |  
823 -| NumX | `RxNum` |  
824 -| DoubleX | `RxDouble` |  
825 -  
826 -RxController and GetBuilder now have merged, you no longer need to memorize which controller you want to use, just use GetxController, it will work for simple state management and for reactive as well.  
827 -  
828 -2- NamedRoutes  
829 -Before:  
830 -  
831 -```dart  
832 -GetMaterialApp(  
833 - namedRoutes: {  
834 - '/': GetRoute(page: Home()),  
835 - }  
836 -)  
837 -```  
838 -  
839 -Now:  
840 -  
841 -```dart  
842 -GetMaterialApp(  
843 - getPages: [  
844 - GetPage(name: '/', page: () => Home()),  
845 - ]  
846 -)  
847 -```  
848 -  
849 -Why this change?  
850 -Often, it may be necessary to decide which page will be displayed from a parameter, or a login token, the previous approach was inflexible, as it did not allow this.  
851 -Inserting the page into a function has significantly reduced the RAM consumption, since the routes will not be allocated in memory since the app was started, and it also allowed to do this type of approach:  
852 -  
853 -```dart  
854 -  
855 -GetStorage box = GetStorage();  
856 -  
857 -GetMaterialApp(  
858 - getPages: [  
859 - GetPage(name: '/', page:(){  
860 - return box.hasData('token') ? Home() : Login();  
861 - })  
862 - ]  
863 -)  
864 -```  
865 -  
866 -# Why Getx?  
867 -  
868 -1- Many times after a Flutter update, many of your packages will break. Sometimes compilation errors happen, errors often appear that there are still no answers about, and the developer needs to know where the error came from, track the error, only then try to open an issue in the corresponding repository, and see its problem solved. Get centralizes the main resources for development (State, dependency and route management), allowing you to add a single package to your pubspec, and start working. After a Flutter update, the only thing you need to do is update the Get dependency, and get to work. Get also resolves compatibility issues. How many times a version of a package is not compatible with the version of another, because one uses a dependency in one version, and the other in another version? This is also not a concern using Get, as everything is in the same package and is fully compatible.  
869 -  
870 -2- Flutter is easy, Flutter is incredible, but Flutter still has some boilerplate that may be unwanted for most developers, such as `Navigator.of(context).push (context, builder [...]`. Get simplifies development. Instead of writing 8 lines of code to just call a route, you can just do it: `Get.to(Home())` and you're done, you'll go to the next page. Dynamic web urls are a really painful thing to do with Flutter currently, and that with GetX is stupidly simple. Managing states in Flutter, and managing dependencies is also something that generates a lot of discussion, as there are hundreds of patterns in the pub. But there is nothing as easy as adding a ".obs" at the end of your variable, and place your widget inside an Obx, and that's it, all updates to that variable will be automatically updated on the screen.  
871 -  
872 -3- Ease without worrying about performance. Flutter's performance is already amazing, but imagine that you use a state manager, and a locator to distribute your blocs/stores/controllers/ etc. classes. You will have to manually call the exclusion of that dependency when you don't need it. But have you ever thought of simply using your controller, and when it was no longer being used by anyone, it would simply be deleted from memory? That's what GetX does. With SmartManagement, everything that is not being used is deleted from memory, and you shouldn't have to worry about anything but programming. You will be assured that you are consuming the minimum necessary resources, without even having created a logic for this.  
873 -  
874 -4- Actual decoupling. You may have heard the concept "separate the view from the business logic". This is not a peculiarity of BLoC, MVC, MVVM, and any other standard on the market has this concept. However, this concept can often be mitigated in Flutter due to the use of context.  
875 -If you need context to find an InheritedWidget, you need it in the view, or pass the context by parameter. I particularly find this solution very ugly, and to work in teams we will always have a dependence on View's business logic. Getx is unorthodox with the standard approach, and while it does not completely ban the use of StatefulWidgets, InitState, etc., it always has a similar approach that can be cleaner. Controllers have life cycles, and when you need to make an APIREST request for example, you don't depend on anything in the view. You can use onInit to initiate the http call, and when the data arrives, the variables will be populated. As GetX is fully reactive (really, and works under streams), once the items are filled, all widgets that use that variable will be automatically updated in the view. This allows people with UI expertise to work only with widgets, and not have to send anything to business logic other than user events (like clicking a button), while people working with business logic will be free to create and test the business logic separately.  
876 -  
877 -This library will always be updated and implementing new features. Feel free to offer PRs and contribute to them.  
878 -  
879 -# Community  
880 -  
881 -## Community channels  
882 -  
883 -GetX has a highly active and helpful community. If you have questions, or would like any assistance regarding the use of this framework, please join our community channels, your question will be answered more quickly, and it will be the most suitable place. This repository is exclusive for opening issues, and requesting resources, but feel free to be part of GetX Community.  
884 -  
885 -| **Slack** | **Discord** | **Telegram** |  
886 -| :-------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------- |  
887 -| [![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](https://communityinviter.com/apps/getxworkspace/getx) | [![Discord Shield](https://img.shields.io/discord/722900883784073290.svg?logo=discord)](https://discord.com/invite/9Hpt99N) | [![Telegram](https://img.shields.io/badge/chat-on%20Telegram-blue.svg)](https://t.me/joinchat/PhdbJRmsZNpAqSLJL6bH7g) |  
888 -  
889 -## How to contribute  
890 -  
891 -_Want to contribute to the project? We will be proud to highlight you as one of our collaborators. Here are some points where you can contribute and make Get (and Flutter) even better._  
892 -  
893 -- Helping to translate the readme into other languages.  
894 -- Adding documentation to the readme (a lot of Get's functions haven't been documented yet).  
895 -- Write articles or make videos teaching how to use Get (they will be inserted in the Readme and in the future in our Wiki).  
896 -- Offering PRs for code/tests.  
897 -- Including new functions.  
898 -  
899 -Any contribution is welcome!  
900 -  
901 -## Articles and videos  
902 -  
903 -- [Dynamic Themes in 3 lines using GetX™](https://medium.com/swlh/flutter-dynamic-themes-in-3-lines-c3b375f292e3) - Tutorial by [Rod Brown](https://github.com/RodBr).  
904 -- [Complete GetX™ Navigation](https://www.youtube.com/watch?v=RaqPIoJSTtI) - Route management video by Amateur Coder.  
905 -- [Complete GetX State Management](https://www.youtube.com/watch?v=CNpXbeI_slw) - State management video by Amateur Coder.  
906 -- [GetX™ Other Features](https://youtu.be/ttQtlX_Q0eU) - Utils, storage, bindings and other features video by Amateur Coder.  
907 -- [Firestore User with GetX | Todo App](https://www.youtube.com/watch?v=BiV0DcXgk58) - Video by Amateur Coder.  
908 -- [Firebase Auth with GetX | Todo App](https://www.youtube.com/watch?v=-H-T_BSgfOE) - Video by Amateur Coder.  
909 -- [The Flutter GetX™ Ecosystem ~ State Management](https://medium.com/flutter-community/the-flutter-getx-ecosystem-state-management-881c7235511d) - State management by [Aachman Garg](https://github.com/imaachman).  
910 -- [GetX, the all-in-one Flutter package](https://www.youtube.com/watch?v=IYQgtu9TM74) - A brief tutorial covering State Management and Navigation by Thad Carnevalli.  
911 -- [Build a To-do List App from scratch using Flutter and GetX](https://www.youtube.com/watch?v=EcnqFasHf18) - UI + State Management + Storage video by Thad Carnevalli.  
912 -- [GetX Flutter Firebase Auth Example](https://medium.com/@jeffmcmorris/getx-flutter-firebase-auth-example-b383c1dd1de2) - Article by Jeff McMorris.  
1 -![](get.png)  
2 -  
3 -*Languages: [English](README.md), [Brazilian Portuguese](README.pt-br.md), [Spanish](README-es.md), Polish (Jesteś tu).*  
4 -  
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)  
7 -[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart)  
8 -[![Discord Shield](https://img.shields.io/discord/722900883784073290.svg?logo=discord)](https://discord.com/invite/9Hpt99N)  
9 -[![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](https://communityinviter.com/apps/getxworkspace/getx)  
10 -[![Telegram](https://img.shields.io/badge/chat-on%20Telegram-blue.svg)](https://t.me/joinchat/PhdbJRmsZNpAqSLJL6bH7g)  
11 -<a href="https://github.com/Solido/awesome-flutter">  
12 - <img alt="Awesome Flutter" src="https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square" />  
13 -</a>  
14 -<a href="https://www.buymeacoffee.com/jonataslaw" target="_blank"><img src="https://i.imgur.com/aV6DDA7.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" > </a>  
15 -  
16 -  
17 -![](getx.png)  
18 -  
19 -- [Kanały komunikacji i wsparcia:](#kanały-komunikacji-i-wsparcia)  
20 -- [Wprowadzenie](#wprowadzenie)  
21 -- [Instalacja](#instalacja)  
22 -- [Counter App z GetX](#counter-app-z-getx)  
23 -- [Trzy fialary](#trzy-filary)  
24 - - [Menadżer stanu](#menadżer-stanu)  
25 - - [Reaktywny menadżer stanu](#reaktywny-menadżer-stanu)  
26 - - [Bardziej szczegółowo o menadżerze stanu](#bardziej-szczegółowo-o-menadżerze-stanu)  
27 - - [Video tłumaczące użycie menadżera stanu](#video-tłumaczące-użycie-menadżera-stanu)  
28 - - [Zarzadzanie routami](#zarządzanie-routami)  
29 - - [Więcej o routach](#więcej-o-routach)  
30 - - [Video tłumaczące użycie](#video-tłumaczące-użycie)  
31 - - [Zarządzanie dependencies](#zarządzanie-dependencies)  
32 - - [Bardziej szczefółowo o menadżerze dependencies](#bardziej-szczegółowo-o-menadżerze-dependencies)  
33 -- [Jak włożyć coś od siebie](#jak-włożyć-coś-od-siebie)  
34 -- [Narzędzia](#narzędzia)  
35 - - [Zmiana motywu](#zmiana-motywu)  
36 - - [Inne zaawansowane API](#inne-zaawansowane-api)  
37 - - [Opcjonalne globalne ustawienia i manualna konfiguracja](#opcjonalne-globalne-ustawienia-i-manualna-konfiguracja)  
38 - - [Video tłumaczace inne funkcjonalności GetX](#video-tłumaczące-inne-funkcjonalności-getx)  
39 -- [Zmiany od 2.0](#zmiany-od-20)  
40 -  
41 -  
42 -# Kanały komunikacji i wsparcia:  
43 -  
44 -[**Slack (English)**](https://communityinviter.com/apps/getxworkspace/getx)  
45 -  
46 -[**Discord (English and Portuguese)**](https://discord.com/invite/9Hpt99N)  
47 -  
48 -[**Telegram (Portuguese)**](https://t.me/joinchat/PhdbJRmsZNpAqSLJL6bH7g)  
49 -  
50 -# Wprowadzenie  
51 -- GetX jest bardzo lekką i potężną biblioteką do Flattera. Łączy wysoką wydajność menadżera stanu, inteligętne dodawanie dependencies i zarządzanie routami w szybki i praktyczny sposób.  
52 -- GetX nie jest dla wszystkich, skupia się na jak najmniejszej konsumpcji zasobów (wydajności) ([zobacz benchmarki](https://github.com/jonataslaw/benchmarks)), używaniu łatwej skłani (produktywności) i daniu możliwości pełnego rozbicia View na z logiki biznesowej (organizacja).  
53 -- GetX która da Ci supermoce i zwiększy produktywność w tworzeniu projektu. Oszczędzi godziny zarówno początkującym jak i ekspoertom.  
54 -- Nawiguj bez podawania `context`, używaj open `dialogs`, `snackbarów` oraz `bottomsheetów` z każdego miejsca w kodzie. Zarządzaj stanami i dodawaj dependencies w prosty i praktyczny sposób!  
55 -- Get jest bezpieczny, stabilny i aktualny. Oprócz tego oferuje szeroki zakres API, które nie są zawarte w standardowym frameworku.  
56 -- GetX nie jest przytłaczający. Ma wiele funkcjonalności pozwalajacych na rozpoczęcie programowania bez martwienia się o nic, ale wszystkie te funkcjonalności są w osobnych kontenerach będących dodane dopiero po ich użyciu. Jeśli tylko używasz menadżera stanu, tylko on będzie kompilowany. Jeśli używasz routów, lecz nic z menadżera stanu on nie będzie kompilowany. Możesz skompilować repozytorium benchmark i zobaczysz że używa tylko menadżera stanu. Aplikacje używajace Get są mniejsze niz inne ponieważ wszystkie rozwiązania GetX sa projektowane dla lekkości i wydajności. Jest to też zasługa Flutterowego AOT, które jest niesamowite i eliminuje nieużywane zasoby jak żaden inny framework.  
57 -  
58 -**GetX zwiększa stwoja produktywność, lecz mozesz to jeszcze przyspieszyć instalując rozszerzenie [GetX extension](https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets) do swojego VSCode**. Jeszcze nie dostępne w innych IDE.  
59 -  
60 -# Instalacja  
61 -  
62 -Dodaj Get do swojego pliku pubspec.yaml:  
63 -  
64 -```yaml  
65 -dependencies:  
66 - get:  
67 -```  
68 -  
69 -Zaimportuj Get do plików w których chcesz go użyć:  
70 -  
71 -```dart  
72 -import 'package:get/get.dart';  
73 -```  
74 -  
75 -# Counter App z GetX  
76 -  
77 -Przykładowa aplikaja tworzona domyślnie podczas kreacji nowego projektu we Flaterze ma ponad 100 lini kodu (z komentarzami). By pokazać siłę Get pokarzę jak zrobić "licznik" ze zmienianą stan z każdym kliknięciem, zmianą stron i udostępniajac stan pomiędzy ekranami. Wszystko w zorganizowany sposób dzieląc buissnes logic z view w zaledwie 26 LINI KODU WŁĄCZAJĄC W TO KOMENTARZE.  
78 -  
79 --Krok 1:  
80 -Dodaj "Get" przed MaterialApp, zamieniając je na GetMaterialApp  
81 -  
82 -  
83 -```dart  
84 -void main() => runApp(GetMaterialApp(home: Home()));  
85 -```  
86 -  
87 -- Note: nie jest to modyfikaja MaterialApp, ponieważ GetMaterialApp nie jest zmodyfikowanym MaterialApp z Fluttera, jest tylko zkonfigurowanym Widgetem mającym domyślnie MaterialApp jako dziecko. Możesz to konfigurować ręcznie, ale nie jest to konieczne. GetMaterialApp jest niezbędne dla działania routów, snackbarów, bootomsheetów, internacjonalizacji, dialogów i wysokopoziomowych api powiązanych z routami i nieobecnościa kontekstu. Nie jest to jednak wymagane do używania zarzadzania stanem i dependencies.  
88 -  
89 --Krok 2:  
90 -Tworzymy klasę business logic i umieszczmy w niej wszystkie zmienne, metody oraz kontrolery. Możesz zmienić zmienna=ą na obserwowalną używajac prostego ".obs"  
91 -  
92 -```dart  
93 -class Controller extends GetxController{  
94 - var count = 0.obs;  
95 - increment() => count.value++;  
96 -}  
97 -```  
98 -- Krok 3:  
99 -Tworzymy View. Użyj StatelessWidget oszczędzajac przy tym RAM. Z Get nie będzie Ci potrzebny StatefullWidget.  
100 -  
101 -  
102 -```dart  
103 -class Home extends StatelessWidget {  
104 -  
105 - // Instantiate your class using Get.put() to make it available for all "child" routes there.  
106 - final Controller c = Get.put(Controller());  
107 -  
108 - @override  
109 - Widget build(context) => Scaffold(  
110 - // Use Obx(()=> to update Text() whenever count is changed.  
111 - appBar: AppBar(title: Obx(() => Text("Clicks: " + c.count.string))),  
112 -  
113 - // Replace the 8 lines Navigator.push by a simple Get.to(). You don't need context  
114 - body: Center(child: RaisedButton(  
115 - child: Text("Go to Other"), onPressed: () => Get.to(Other()))),  
116 - floatingActionButton:  
117 - FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment));  
118 -}  
119 -  
120 -class Other extends StatelessWidget {  
121 - // You can ask Get to find a Controller that is being used by another page and redirect you to it.  
122 - final Controller c = Get.find();  
123 -  
124 - @override  
125 - Widget build(context){  
126 - // Access the updated count variable  
127 - return Scaffold(body: Center(child: Text(c.count.string)));  
128 - }  
129 -}  
130 -```  
131 -Wynik:  
132 -  
133 -![](counter-app-gif.gif)  
134 -  
135 -Jest to prosty projekt, ale już na jego przykładzie widać potęgę Get. Wzraz ze wzrostem rozmiaru aplikacji ta różnica tylko się powieksza.  
136 -  
137 -Get był projektowany dla pracy z zespołem, ale równie dobrze sprawdza się w indywidualnej pracy.  
138 -  
139 -Zawsze dotrzymuj deadlinów i dostarczaj swoje rozwiązania na czas bez straty na wydajności. Get nie jest dla wszystkich jak już wspominałem, ale jeśli identyfikujesz się z powyższym zdaniem Get jest dla ciebie.  
140 -  
141 -# Trzy filary  
142 -  
143 -## Menadżer stanu  
144 -  
145 -Obecnie istnieje kilka menadżeów dla Fluttera. Jednak większość z nich wymaga używania ChangeNotifier, po to aby zaktualizować widżety, co nie sprawdza się pod kątem wydajności w średnich i dużych aplikacach. Możesz sprawdzić w oficjalnej dokumentacji, że ChangeNotifier powinien być używany z maksimum dwoma listinerami (https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html), będąc praktycznie bezużytecznym w średnich i duzych projektach.  
146 -  
147 -Get nie jest ani lepszy, ani gorszy od innych menadżerów stanów, ale powinieneś rozpatrzyć te punkty jak i poniższe, aby wybrać między użyciem Get w czystej formie (Vanilla), albo używaniem go wraz z innym menadżerem.  
148 -  
149 -Definitywnie Get nie jest przeciwnikiem żadnego innego menadżera, ponieważ jest on mikroframeworkiem, nie tylko menadżerem stanu. Może być użyty samodzielnie, lub w koegzystencji.  
150 -  
151 -Get ma bardzo lekki i prosty menadżer stanu (napisany w tylko 95 lini kodu), który nie używa ChangeNotifier. Sprosta on wymaganiom szczególnie nowych we Flutterze i nie sprawi problemu nawer w dużych aplikacjach.  
152 -  
153 -### Reaktywny menadżer stanu  
154 -  
155 -Reaktywne programowanie możee dotrącać niektórych, ponieważ powszechnie jest uważane za skomplikowane. GetX zamienia to w coś prostego:  
156 -  
157 -- Nie musisz tworzyć Strw=eamControllerów,  
158 -- Nie musisz tworzyć StreamBuildera dla każdej zmiennej,  
159 -- Nie ma potrzeby tworzenia klasy dla kżdego stanu,  
160 -- Nie musisz tworzyć Get dla inicjalnej zmiennej  
161 -  
162 -Wyobraź sobie, że masz zmienną i za każdym razem jak zmienisz ją chcesz żeby wszystkie widżety używające jej automatycznie się zmieniły  
163 -  
164 -Przykładowa zmienna:  
165 -```dart  
166 -var name = 'Jonatas Borges';  
167 -```  
168 -  
169 -By zamienić ją na obserwowalną dodaj ".obx" na końcu:  
170 -  
171 -```dart  
172 -var name = 'Jonatas Borges'.obs;  
173 -```  
174 -  
175 -I w UI, kiedy chcesz go zaktualizować przy modyfikacji zmiennej po prostu dodaj to:  
176 -```dart  
177 -Obx (() => Text (controller.name));  
178 -```  
179 -  
180 -To wszystko. *Proste*, co nie?  
181 -  
182 -### Bardziej szczegółowo o menadżerze stanu  
183 -**Zobacz bardziej szczegółowe wytłumaczenie menadz=żera sranu [tutaj](./documentation/en_US/state_management.md). Znajdują się tam przykłady jak o różnice między prostym menadżerem stanu oraz reaktywnym**  
184 -  
185 -### Video tłumaczące użycie menadżera stanu  
186 -  
187 -Amateur COder nagrał o tym niezwykły film:  
188 -  
189 -Link: [Complete GetX State Management](https://www.youtube.com/watch?v=CNpXbeI_slw)  
190 -  
191 -## Zarządzanie routami  
192 -  
193 -Jeśli chcesz używać routes/snackbars/dialogs/bottomsheets z GetX możesz to robić bez contextu.  
194 -  
195 -Zamień MaterialApp na GetMaterialApp  
196 -```dart  
197 -GetMaterialApp( // Before: MaterialApp(  
198 - home: MyHome(),  
199 -)  
200 -```  
201 -  
202 -By nawigować do nowego ekranu:  
203 -  
204 -```dart  
205 -Get.to(NextScreen());  
206 -```  
207 -  
208 -By powrócić do poprzedniego ekranu  
209 -  
210 -```dart  
211 -Get.back();  
212 -```  
213 -  
214 -By przejść do następnego ekranu bez możliwości powrotu do poprzedniego (do zastosowania SplashScreenów, ekranów logowania itd.)  
215 -  
216 -```dart  
217 -Get.off(NextScreen());  
218 -```  
219 -  
220 -By przejść do następnego ekranu niszcząc poprzednie routy (użyteczne w koszykach, ankietach i testach)  
221 -  
222 -```dart  
223 -Get.offAll(NextScreen());  
224 -```  
225 -  
226 -By nawigować do następnego routa i otrzymać, lub uaktualnić dane zaraz po tym jak z niego wrócisz:  
227 -```dart  
228 -var data = await Get.to(Payment());  
229 -```  
230 -w innym ekranie wyślij dane z poprzedniego routa:featury  
231 -  
232 -```dart  
233 -Get.back(result: 'sucess');  
234 -```  
235 -I użyj następujące np.:  
236 -```dart  
237 -if(data == 'sucess') madeAnything();  
238 -```  
239 -Zobacz, ze do żadnej z tych operacji nie potrzebowałeś contextu. Jest to jedna z głównych zalet GetX oszczędzającego na niepotrzebnej ogudowie z kod i dającego możliwość uzywania tych metod w klasie kontrolera.  
240 -  
241 -  
242 -### Więcej o routach  
243 -  
244 -**Get używa named routes i także oferuje niskopoziomową obsługę routów! Zobacz bardziej szczegółową dokumentacje [tutaj](./documentation/en_US/route_management.md)**  
245 -  
246 -### Video tłumaczące użycie  
247 -  
248 -Amateur Coder nagrał o tym niezwykły film:  
249 -  
250 -Link: [Complete GetX Navigation](https://www.youtube.com/watch?v=RaqPIoJSTtI)  
251 -  
252 -## Zarządzanie dependencies  
253 -  
254 -Get ma prosty i potężny menadżer dependencies. Pozwala on na otrzymanie tych samych klas jak twoje Bloc lub Kontroler piszac jedną linię kodu bez Provider context i inheritedWidget:  
255 -  
256 -```dart  
257 -Controller controller = Get.put(Controller()); // Rather Controller controller = Controller();  
258 -```  
259 -  
260 -- Note: Jeśli używasz menadżera stanu Get zwróć uwafę na binding api, które pozwoli Ci łatwiej połączyć twój widok z kontrolerem.  
261 -https://github.com/jonataslaw/get  
262 -**Tip:** Menadżer dependency Get jest oddzielony od innych części pakietu więc jeśli już używasz menadzera stanu(którego kolwiek,bez różnicy) nie musisz przepisywać tego wszystkiego na nowo. Możesz używać tego dodawania dependencies bez poroblemu.  
263 -  
264 -```dart  
265 -controller.fetchApi();  
266 -```  
267 -Wyobraź sobie, że musisz nawigować pomiędzy wieloma routami i potrzebujesz dane z kontrolerów z poprzednich ekranów. Musiałbyś użyć menadżera stanu z dodatkiem Providera albo Get_it, prawda? Otuż nie z Fet. Muszisz po prostu poprosić Get o znalezienie tego kontrolera i nie potrzebujesz przy tym dodatkowych dependencies.  
268 -  
269 -```dart  
270 -Controller controller = Get.find();  
271 -//Yes, it looks like Magic, Get will find your controller, and will deliver it to you. You can have 1 million controllersfeatury instantiated, Get will always give you the right controller.  
272 -```  
273 -  
274 -I wtedy będziesz mógł otrzymać bez problemu z niego dane  
275 -  
276 -```dart  
277 -Text(controller.textFromApi);  
278 -```  
279 -### Bardziej szczegółowo o menadżerze dependencies  
280 -  
281 -**Zobzcz więcej w dokumentacji [tutaj](./documentation/en_US/dependency_management.md)**  
282 -  
283 -# Jak włożyć coś od siebie  
284 -  
285 -Możesz uczestniczyć w rozwoju projektu na różny sposób:  
286 -- Pomagając w tłumaczeniu readme na inne języki.  
287 -- Dodając dokumentację do readme ( nawet nie połowa funkcji została jeszcze opisana).  
288 -- Pisząc artykuły i nagrywając filmy uczące użycia biblioteki Get (będą zamieszczone w readme, a w przyszłości na naszej Wiki).  
289 -- Oferując PR-y dla kodu i testów.  
290 -- Dodając nowe funkcje.  
291 -  
292 -Każda współpraca jest mile widziana!  
293 -  
294 -# Narzędzia  
295 -  
296 -## Zmiana motywu  
297 -  
298 -Nie powinno się uzywać innego widżetu niż GetMaterialApp by go zaktualizować. To może powodować duplikacje kluczy. Wiele osób nawykło do prehistorycznego podejścia tworzenia widżetu "ThemeProvider" tylko po to by zmienić motyw aplikacji. Z Get nie jest to absolutnie wymagane.  
299 -  
300 -Możesz stworzyć customowy motyw i łatwo go dodać z Get.changeTheme bez niepotrzebnego kodu.  
301 -  
302 -```dart  
303 -Get.changeTheme(ThemeData.light());  
304 -```  
305 -  
306 -Jeśli chcesz stworzyć coś jak przycisk zmieniający motyw aplikacji na onTap, możesz połączyć dwia Get API. Api sprawdzające czy ciemny motyw jest używany i Api zajmujące się zmianą motywu. Po prostu użyj tego w onPressed:  
307 -  
308 -```dart  
309 -Get.changeTheme(Get.isDarkMode? ThemeData.light(): ThemeData.dark());featury  
310 -```  
311 -  
312 -Kiedy ciemny motyw jest aktywny zmieni się on na jasny, w przeciwnym wypadku zmieni się na ciemny.  
313 -  
314 -Jeśli interesuje Cię jak zmieniać motywy podąrzaj za samouczkiem na Medium uczącym zmiany motywu z Get:  
315 -  
316 -- [Dynamic Themes in 3 lines using Get](https://medium.com/swlh/flutter-dynamic-themes-in-3-lines-c3b375f292e3) - Samouczek stworzony przez [Rod Brown](https://github.com/RodBr).  
317 -  
318 -## Inne zaawansowane API  
319 -  
320 -```dart  
321 -// give the current args from currentScreen  
322 -Get.arguments  
323 -  
324 -// give arguments of previous route  
325 -Get.previousArguments  
326 -  
327 -// give name of previous route  
328 -Get.previousRoute  
329 -  
330 -// give the raw route to access for example, rawRoute.isFirst()  
331 -Get.rawRoute  
332 -  
333 -// give access to Rounting API from GetObserver  
334 -Get.routing  
335 -  
336 -// check if snackbar is open  
337 -Get.isSnackbarOpen  
338 -  
339 -// check if dialog is open  
340 -Get.isDialogOpen  
341 -  
342 -// check if bottomsheet is opefeaturyn  
343 -Get.isBottomSheetOpen  
344 -  
345 -// remove one route.  
346 -Get.removeRoute()  
347 -  
348 -// back repeatedly until the predicate returns true.  
349 -Get.until()  
350 -  
351 -// go to next route and remove all the previous routes until the predicate returns true.  
352 -Get.offUntil()  
353 -  
354 -// go to next named route and remove all the previous routes until the predicate returns true.  
355 -Get.offNamedUntil()  
356 -  
357 -//Check in what platform the app is running  
358 -GetPlatform.isAndroid  
359 -GetPlatform.isIOS  
360 -GetPlatform.isWeb  
361 -  
362 -// Equivalent to the method: MediaQuery.of(context).size.height, but they are immutable.  
363 -Get.height  
364 -Get.width  
365 -  
366 -// Gives the current context of navigator.  
367 -Get.context  
368 -  
369 -// Gives the context of the snackbar/dialog/bottomsheet in the foreground anywhere in your code.  
370 -Get.contextOverlay  
371 -  
372 -// Note: the following methods are extensions on context. Since you  
373 -// have access to context in any place of your UI, you can use it anywhere in the UI code  
374 -  
375 -// If you need a changeable height/width (like browser windows that can be scfeaturyaled) you will need to use context.  
376 -context.width  
377 -context.height  
378 -  
379 -// gives you the power to define half the screen now, a third of it and so on.  
380 -//Useful for responsive applications.  
381 -// param dividedBy (double) optional - default: 1  
382 -// param reducedBy (double) optional - default: 0  
383 -context.heightTransformer()  
384 -context.widthTransformer()  
385 -  
386 -/// similar to MediaQuery.of(context).size  
387 -context.mediaQuerySize()  
388 -  
389 -/// similar to MediaQuery.of(context).padding  
390 -context.mediaQueryPadding()  
391 -  
392 -/// similar to MediaQuery.of(context).viewPadding  
393 -context.mediaQueryViewPadding()  
394 -  
395 -/// similar to MediaQuery.of(context).viewInsets;  
396 -context.mediaQueryViewInsets()  
397 -  
398 -/// similar to MediaQuery.of(context).orientation;  
399 -context.orientation()  
400 -  
401 -/// check if device is on landscape mode  
402 -context.isLandscape()  
403 -  
404 -/// check if device is on portrait mode  
405 -context.isPortrait()  
406 -  
407 -/// similar to MediaQuery.of(context).devicePixelRatio;  
408 -context.devicePixelRatio()  
409 -  
410 -/// similar to MediaQuery.of(context).textScaleFactor;  
411 -context.textScaleFactor()  
412 -  
413 -/// get the shortestSide from screen  
414 -context.mediaQueryShortestSide()  
415 -  
416 -/// True if width be larger thfeaturyan 800  
417 -context.showNavbar()  
418 -  
419 -/// True if the shortestSide is smaller than 600p  
420 -context.isPhone()  
421 -  
422 -/// True if the shortestSide is largest than 600p  
423 -context.isSmallTablet()  
424 -  
425 -/// True if the shortestSide is largest than 720p  
426 -context.isLargeTablet()  
427 -  
428 -/// True if the current device is Tablet  
429 -context.isTablet()  
430 -```  
431 -  
432 -### Opcjonalne globalne ustawienia i manualna konfiguracja  
433 -  
434 -GetMaterialApp konfiguruje wszystko za Ciebie, ale jeśli chcesz możesz konfigurować Get manualnie.  
435 -  
436 -```dart  
437 -MaterialApp(  
438 - navigatorKey: Get.key,  
439 - navigatorObservers: [GetObserver()],  
440 -);  
441 -```  
442 -  
443 -Będziesz mógł używać swojego Midware z GetObserver, nie wpływa to na nic.  
444 -  
445 -```dart  
446 -MaterialApp(  
447 - navigatorKey: Get.key,  
448 - navigatorObservers: [  
449 - GetObserver(MiddleWare.observer) // Here  
450 - ],  
451 -);  
452 -```  
453 -  
454 -Mozesz stworzyć globalne ustawienia dla Get. Tylko dodaj Get.config do swojego kodu przed użyciem routów, lub bezpośrednio w GetMaterialApp  
455 -  
456 -```dart  
457 -GetMaterialApp(  
458 - enableLog: true,  
459 - defaultTransition: Transition.fade,  
460 - opaqueRoute: Get.isOpaqueRouteDefault,  
461 - popGesture: Get.isPopGestureEnable,  
462 - transitionDuration: Get.defaultDurationTransition,  
463 - defaultGlobalState: Get.defaultGlobalState,https://github.com/jonataslaw/ge  
464 -);  
465 -  
466 -Get.config(  
467 - enableLog = true,  
468 - defaultPopGesture = true,  
469 - defaultTransition = Transitions.cupertino  
470 -)  
471 -```  
472 -  
473 -Opcjonalnie możesz przekierować wszystkie logi z Get by używać swojej ulubionej paczki i zbierać w niej logi.  
474 -  
475 -```dart  
476 -GetMaterialApp(  
477 - enableLog: true,  
478 - logWriterCallback: localLogWriter,  
479 - );  
480 - void localLogWriter(String text, {bool isError = false}) {  
481 - // tutaj przekaż wiadomosci do ulubionej paczki  
482 - // pamiętaj że nawet jeśli "enableLog: false" logi i tak będą wysłane w tym callbacku  
483 - // Musisz sprawdzić konfiguracje flag jeśli chcesz przez GetConfig.isLogEnable  
484 - }  
485 -```  
486 -## Video tłumaczące inne funkcjonalności GetX  
487 -  
488 -  
489 -Amateur Coder nagrał niezwykły film tłumaczący powyższe zagadnienia!  
490 -  
491 -Link: [GetX Other Features](https://youtu.be/ttQtlX_Q0eU)  
492 -  
493 -  
494 -# Zmiany od 2.0  
495 -  
496 -1- Typy Rx:  
497 -  
498 -| Przed | Po |  
499 -| ------- | ---------- |  
500 -| StringX | `RxString` |  
501 -| IntX | `RxInt` |  
502 -| MapX | `RxMax` |  
503 -| ListX | `RxList` |  
504 -| NumX | `RxNum` |  
505 -| DoubleX | `RxDouble` |  
506 -  
507 -RXController i GetBuilder teraz zostały połączone. Nie musisz już pamiętać którego kontrolerachcesz użyć, po prostu korzystaj z GetxController, będzie działać zarówno dla prostego jak i reaktywnego menadżera stanów.  
508 -  
509 -2- NamedRoutes  
510 -Wcześniej:  
511 -  
512 -```dart  
513 -GetMaterialApp(  
514 - namedRoutes: {  
515 - '/': GetRoute(page: Home()),  
516 - }  
517 -)  
518 -```  
519 -  
520 -Teraz:  
521 -  
522 -```dart  
523 -GetMaterialApp(  
524 - getPages: [  
525 - GetPage(name: '/', page: () => Home()),  
526 - ]  
527 -)  
528 -```  
529 -  
530 -Po co ta zmiana?  
531 -Często może być niezbędnym decydowanie która strona będzie wyswietlana w zależności od parametru, lub tokenu logowania. Wczesniejsze podejscie było nieelastyczne nie pozwalając na to. Zawarcie strony w funkcji zmniejszyło sporzycie RAM-u, ze względu na niealokowanie routów od początku działania aplikacji. Pozwoliło to także na takie podejscie:  
532 -  
533 -```dart  
534 -  
535 -GetStorage box = GetStorage();  
536 -  
537 -GetMaterialApp(  
538 - getPages: [  
539 - GetPage(name: '/', page:(){  
540 - return box.hasData('token') ? Home() : Login();  
541 - })  
542 - ]  
543 -)  
544 -```  
1 -![](get.png)  
2 -  
3 -*Idiomas: [Inglês](README.md), Português Brasileiro (este arquivo), [Espanhol](README-es.md), [Polaco](README.pl.md).*  
4 -  
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)  
7 -[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart)  
8 -[![Discord Shield](https://img.shields.io/discord/722900883784073290.svg?logo=discord)](https://discord.com/invite/9Hpt99N)  
9 -[![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](https://communityinviter.com/apps/getxworkspace/getx)  
10 -[![Telegram](https://img.shields.io/badge/chat-on%20Telegram-blue.svg)](https://t.me/joinchat/PhdbJRmsZNpAqSLJL6bH7g)  
11 -<a href="https://github.com/Solido/awesome-flutter">  
12 - <img alt="Awesome Flutter" src="https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square" />  
13 -</a>  
14 -<a href="https://www.buymeacoffee.com/jonataslaw" target="_blank"><img src="https://i.imgur.com/aV6DDA7.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" > </a>  
15 -  
16 -  
17 -![](getx.png)  
18 -  
19 -<h2> Pedimos desculpas por qualquer parte não traduzida aqui. O GetX™ é atualizado com muita frequência e as traduções podem não vir ao mesmo tempo. Então, para manter essa documentação pelo menos com tudo que a versão em inglês tem, eu vou deixar todos os textos não-traduzidos aqui (eu considero que é melhor ele estar lá em inglês do que não estar), então se alguém quiser traduzir, seria muito útil 😁</h2>  
20 -  
21 -- [Sobre Get](#sobre-get)  
22 -- [Instalando](#instalando)  
23 -- [App Counter usando GetX](#app-counter-usando-getx)  
24 -- [Os três pilares](#os-três-pilares)  
25 - - [Gerenciamento de estado](#gerenciamento-de-estado)  
26 - - [Reactive state manager](#reactive-state-manager)  
27 - - [Mais detalhes sobre gerenciamento de estado](#mais-detalhes-sobre-gerenciamento-de-estado)  
28 - - [Explicação em video do gerenciamento de estado](#explicação-em-video-do-gerenciamento-de-estado)  
29 - - [Gerenciamento de rotas](#gerenciamento-de-rotas)  
30 - - [Mais detalhes sobre gerenciamento de rotas](#mais-detalhes-sobre-gerenciamento-de-rotas)  
31 - - [Explicação em video do gerenciamento de rotas](#explicação-em-video-do-gerenciamento-de-rotas)  
32 - - [Gerenciamento de Dependência](#gerenciamento-de-dependência)  
33 - - [Mais detalhes sobre gerenciamento de dependências](#mais-detalhes-sobre-gerenciamento-de-dependências)  
34 -- [Utilidades](#utilidades)  
35 - - [Internacionalização](#internacionalização)  
36 - - [Traduções](#traduções)  
37 - - [Usando traduções](#usando-traduções)  
38 - - [Localidade](#localidade)  
39 - - [Alterar Local](#alterar-local)  
40 - - [Localidade do sistema operacional](#localidade-do-sistema-operacional)  
41 - - [Mudar tema (changeTheme)](#mudar-tema-changetheme)  
42 - - [Outras APIs avançadas](#outras-apis-avançadas)  
43 - - [Configurações Globais opcionais e configurações manuais](#configurações-globais-opcionais-e-configurações-manuais)  
44 - - [Widgets de Estado Local](#widgets-de-estado-local)  
45 - - [ValueBuilder](#valuebuilder)  
46 - - [ObxValue](#obxvalue)  
47 - - [Dicas Úteis](#dicas-úteis)  
48 - - [GetView](#getview)  
49 - - [GetWidget](#getwidget)  
50 - - [GetxService](#getxservice)  
51 - - [Explicação em vídeo sobre Outras Features do GetX](#explicação-em-vídeo-sobre-outras-features-do-getx)  
52 -- [Breaking Changes da versão 2 para 3](#breaking-changes-da-versão-2-para-3)  
53 - - [Tipagem Rx](#tipagem-rx)  
54 - - [RxController e GetBuilder se uniram](#rxcontroller-e-getbuilder-se-uniram)  
55 - - [Rotas nomeadas](#rotas-nomeadas)  
56 - - [Porque essa mudança](#porque-essa-mudança)  
57 -- [Por que GetX?](#por-que-getx)  
58 -- [Comunidade](#comunidade)  
59 - - [Canais da comunidade](#canais-da-comunidade)  
60 - - [Como contribuir](#como-contribuir)  
61 - - [Artigos e vídeos](#artigos-e-vídeos)  
62 -  
63 -# Sobre Get  
64 -  
65 -- Get é uma biblioteca poderosa e extraleve para Flutter. Ela combina um gerenciador de estado de alta performance, injeção de dependência inteligente e gerenciamento de rotas de uma forma rápida e prática.  
66 -- GetX™ possui 3 princípios básicos, o que significa que esta é a prioridade para todos os recursos da biblioteca  
67 - - **PERFOMANCE**: GetX™ é focado em desempenho e consumo mínimo de recursos. Os benchmarks quase sempre não são importantes no mundo real, mas se você quiser, há um indicador de consumo aqui ([benchmarks](https://github.com/jonataslaw/benchmarks)), onde GetX™ se sai melhor do que outras abordagens de gerenciamento de estado, por exemplo. A diferença não é grande, mas mostra nossa preocupação em não desperdiçar seus recursos.  
68 - - **PRODUTIVIDADE**: GetX™ usa uma sintaxe fácil e agradável. Não importa o que você queira fazer, sempre há uma maneira mais fácil com GetX™. Isso economizará horas de desenvolvimento e extrairá o máximo de desempenho que seu aplicativo pode oferecer.  
69 - - **ORGANIZAÇÃO**: GetX™ permite o desacoplamento total da View, lógica de apresentação, lógica de negócios, injeção de dependência e navegação. Você não precisa de contexto para navegar entre as rotas, portanto, você não depende da árvore do widget (visualização) para isso. Você não precisa de contexto para acessar seus Controllers / BLoCs por meio de um inheritedWidget, então você desacopla completamente sua lógica de apresentação e lógica de negócios de sua camada de visualização. Você não precisa injetar suas classes Controllers / Models / BLoCs em sua árvore de widgets através de multiproviders, pois GetX™ usa seu próprio recurso de injeção de dependência, desacoplando a DI de sua View completamente. Com GetX™ você sabe onde encontrar cada recurso de sua aplicação, tendo o código limpo por padrão. Isso além de facilitar a manutenção, torna o compartilhamento dos módulos, algo que até então em Flutter era impensável, algo totalmente possível. O BLoC foi um ponto de partida para organizar o código no Flutter, ele separa a lógica de negócios da visualização. GetX™ é uma evolução natural disso, separando não apenas a lógica de negócios, mas a lógica de apresentação. O bônus da injeção de dependências e rotas também são dissociadas e a camada de dados está fora de tudo. Você sabe onde está tudo e tudo isso de uma maneira mais fácil do que construir um hello world. GetX™ é a maneira mais fácil, prática e escalonável de construir aplicativos de alto desempenho com o Flutter SDK, com um grande ecossistema em torno dele que funciona perfeitamente em conjunto, sendo fácil para iniciantes e preciso para especialistas. É seguro, estável, atualizado e oferece uma grande variedade de APIs integradas que não estão presentes no Flutter SDK padrão.  
70 -- GetX™ não é inchado. Possui uma infinidade de recursos que permitem que você comece a programar sem se preocupar com nada, mas cada um desses recursos está em contêineres separados e só são iniciados após o uso. Se você usar apenas o Gerenciamento de estado, apenas o Gerenciamento de estado será compilado. Se você usar apenas rotas, nada do gerenciamento de estado será compilado. Você pode compilar o repositório de benchmark e verá que usando apenas o gerenciamento de estado Get, o aplicativo compilado com Get tornou-se menor do que todos os outros aplicativos que têm apenas o gerenciamento de estado de outros pacotes, porque nada que não seja usado será compilado em seu código e cada solução GetX™ foi projetada para ser extra leve. O mérito aqui também vem do tree shaking do Flutter, que é incrível e consegue eliminar recursos não utilizados como nenhum outro framework faz.  
71 -- Navegue por rotas sem `context`, abra `Dialog`s, `Snackbar`s ou `BottomSheet`s de qualquer lugar no código, gerencie estados e injete dependências de uma forma simples e prática.  
72 -- GetX™ possui um enorme ecossistema, capaz de rodar com o mesmo código no Android, iOS, Web, Mac, Linux, Windows e em seu servidor. É possível reutilizar totalmente o código feito no front-end em seu back-end com **[Get Server](https://github.com/jonataslaw/get_server)**.  
73 -  
74 -Além disso, todo o processo de desenvolvimento pode ser totalmente automatizado, tanto no servidor quanto no front-end com **[Get CLI](https://github.com/jonataslaw/get_cli)**.  
75 -  
76 -Além disso, para aumentar ainda mais sua produtividade, temos a **[extensão para VSCode](https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets)** e a **[extensão para Android Studio/Intellij](https://plugins.jetbrains.com/plugin/14975-getx-snippets)**  
77 -  
78 -# Instalando  
79 -  
80 -Adicione Get ao seu arquivo pubspec.yaml  
81 -  
82 -```yaml  
83 -dependencies:  
84 - get:  
85 -```  
86 -  
87 -Importe o get nos arquivos que ele for usado:  
88 -  
89 -```dart  
90 -import 'package:get/get.dart';  
91 -```  
92 -  
93 -# App Counter usando GetX  
94 -  
95 -O app 'Counter' criado por padrão no flutter com o comando `flutter create` tem mais de 100 linhas(incluindo os comentários). Para demonstrar o poder do Get, irei demonstrar como fazer o mesmo 'Counter' mudando o estado em cada toque trocando entre páginas e compartilhando o estado entre telas. Tudo de forma organizada, separando a lógica de negócio da View, COM SOMENTE 26 LINHAS INCLUINDO COMENTÁRIOS  
96 -  
97 -- Passo 1:  
98 -Troque `MaterialApp` para `GetMaterialApp`  
99 -  
100 -```dart  
101 -void main() => runApp(GetMaterialApp(home: Home()));  
102 -```  
103 -  
104 -- **Obs:** Isso não modifica o `MaterialApp` do Flutter, GetMaterialApp não é uma versão modificada do MaterialApp, é só um Widget pré-configurado, que tem como child o MaterialApp padrão. Você pode configurar isso manualmente, mas definitivamente não é necessário. GetMaterialApp vai criar rotas, injetá-las, injetar traduções, injetar tudo que você precisa para navegação por rotas (gerenciamento de rotas). Se você quer somente usar o gerenciador de estado ou somente o gerenciador de dependências, não é necessário usar o GetMaterialApp. Ele somente é necessário para:  
105 - - Rotas  
106 - - Snackbars/bottomsheets/dialogs  
107 - - apis relacionadas a rotas e a ausência de `context`  
108 - - Internacionalização  
109 -- **Obs²:** Esse passo só é necessário se você for usar o gerenciamento de rotas (`Get.to()`, `Get.back()` e assim por diante), Se você não vai usar isso então não é necessário seguir o passo 1  
110 -  
111 -- Passo 2:  
112 -Cria a sua classe de regra de negócio e coloque todas as variáveis, métodos e controllers dentro dela.  
113 -Você pode fazer qualquer variável observável usando um simples `.obs`  
114 -  
115 -```dart  
116 -class Controller extends GetxController{  
117 - var count = 0.obs;  
118 - increment() => count.value++;  
119 -}  
120 -```  
121 -  
122 -- Passo 3:  
123 -Crie sua View usando StatelessWidget, já que, usando Get, você não precisa mais usar StatefulWidgets.  
124 -  
125 -```dart  
126 -class Home extends StatelessWidget {  
127 - // Instancie sua classe usando Get.put() para torná-la disponível para todas as rotas subsequentes  
128 - final Controller c = Get.put(Controller());  
129 - @override  
130 - Widget build(context) => Scaffold(  
131 - appBar: AppBar(title: Obx(() => Text("Total de cliques: ${c.count}"))),  
132 - // Troque o Navigator.push de 8 linhas por um simples Get.to(). Você não precisa do 'context'  
133 - body: Center(child: RaisedButton(  
134 - child: Text("Ir pra Outra tela"), onPressed: () => Get.to(Outra()))),  
135 - floatingActionButton: FloatingActionButton(child:  
136 - Icon(Icons.add), onPressed: c.increment));  
137 -}  
138 -  
139 -class Outra extends StatelessWidget {  
140 - // Você pode pedir o Get para encontrar o controller que foi usado em outra página e redirecionar você pra ele.  
141 - final Controller c = Get.find();  
142 - @override  
143 - Widget build(context) => Scaffold(body: Center(child: Text("${c.count}")));  
144 -}  
145 -  
146 -```  
147 -  
148 -Resultado:  
149 -  
150 -![](counter-app-gif.gif)  
151 -  
152 -Esse é um projeto simples mas já deixa claro o quão poderoso o Get é. Enquanto seu projeto cresce, essa diferença se torna bem mais significante.  
153 -  
154 -Get foi feito para funcionar com times, mas torna o trabalho de um desenvolvedor individual simples.  
155 -  
156 -Melhore seus prazos, entregue tudo a tempo sem perder performance. Get não é para todos, mas se você identificar com o que foi dito acima, Get é para você!  
157 -  
158 -  
159 -# Os três pilares  
160 -  
161 -## Gerenciamento de estado  
162 -  
163 -Há atualmente vários gerenciadores de estados para o Flutter. Porém, a maioria deles envolve usar `ChangeNotifier` para atualizar os widgets e isso é uma abordagem muito ruim no quesito performance em aplicações de médio ou grande porte. Você pode checar na documentação oficial do Flutter que o [`ChangeNotifier` deveria ser usado com um ou no máximo dois listeners](https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html), fazendo-o praticamente inutilizável em qualquer aplicação média ou grande.  
164 -  
165 -Get não é melhor ou pior que nenhum gerenciador de estado, mas você deveria analisar esses pontos tanto quanto os argumentos abaixo para escolher entre usar Get na sua forma pura, ou usando-o em conjunto com outro gerenciador de estado.  
166 -  
167 -Definitivamente, Get não é o inimigo de nenhum gerenciador, porque Get é um microframework, não apenas um gerenciador, e pode ser usado tanto sozinho quanto em conjunto com eles.  
168 -  
169 -Get tem dois gerenciadores de estado diferentes: o simple state manager (vamos chamá-lo de GetBuilder) e o reactive state manager (que tem o nome do pacote, GetX)  
170 -  
171 -### Reactive state manager  
172 -  
173 -Programação reativa pode alienar muitas pessoas porque é dito que é complicado. GetX™ transforma a programação reativa em algo bem simples:  
174 -  
175 -* Você não precisa criar StreamControllers  
176 -* Você não precisa criar um StreamBuilder para cada variável  
177 -* Você não precisa criar uma classe para cada estado  
178 -* Você não precisa criar um get para o valor inicial  
179 -  
180 -Programação reativa com o Get é tão fácil quanto usar setState.  
181 -  
182 -Vamos imaginar que você tenha uma variável e quer que toda vez que ela alterar, todos os widgets que a usam são automaticamente alterados.  
183 -  
184 -Essa é sua variável:  
185 -  
186 -```dart  
187 -var name = 'Jonatas Borges';  
188 -```  
189 -  
190 -Para fazer dela uma variável observável, você só precisa adicionar `.obs` no final:  
191 -  
192 -```dart  
193 -var name = 'Jonatas Borges'.obs;  
194 -```  
195 -  
196 -E Na UI, quando quiser mostrar a variável e escutar as mudanças dela, simplesmente faça isso:  
197 -  
198 -```dart  
199 -Obx (() => Text (controller.name));  
200 -```  
201 -  
202 -Só isso. É *simples assim*;  
203 -  
204 -### Mais detalhes sobre gerenciamento de estado  
205 -  
206 -**Veja uma explicação mais completa do gerenciamento de estado [aqui](./documentation/pt_BR/state_management.md). Lá terá mais exemplos e também a diferença do simple state manager do reactive state manager**  
207 -  
208 -### Explicação em video do gerenciamento de estado  
209 -  
210 -Amateur Coder fez um vídeo ótimo sobre o gerenciamento de estado! (em inglês). Link: [Complete GetX State Management](https://www.youtube.com/watch?v=CNpXbeI_slw)  
211 -  
212 -Você vai ter uma boa idea do poder do GetX™  
213 -  
214 -## Gerenciamento de rotas  
215 -  
216 -Se você for usar routes / snackbars / dialogs / bottomsheets sem contexto, GetX™ é excelente para você também, veja:  
217 -  
218 -Adicione "Get" antes do seu MaterialApp, transformando-o em GetMaterialApp  
219 -  
220 -```dart  
221 -GetMaterialApp( // Antes: MaterialApp(  
222 - home: MyHome(),  
223 -)  
224 -```  
225 -  
226 -Para navegar para uma próxima tela:  
227 -  
228 -```dart  
229 -Get.to(ProximaTela());  
230 -```  
231 -  
232 -Para fechar snackbars, dialogs, bottomsheets, ou qualquer coisa que você normalmente fecharia com o `Navigator.pop(context)` (como por exemplo fechar a View atual e voltar para a anterior):  
233 -  
234 -```dart  
235 -Get.back();  
236 -```  
237 -  
238 -Para ir para a próxima tela e NÃO deixar opção para voltar para a tela anterior (bom para SplashScreens, telas de login e etc.):  
239 -  
240 -```dart  
241 -Get.off(ProximaTela());  
242 -```  
243 -  
244 -Para ir para a próxima tela e cancelar todas as rotas anteriores (útil em telas de carrinho, votações ou testes):  
245 -  
246 -```dart  
247 -Get.offAll(ProximaTela());  
248 -```  
249 -  
250 -Para navegar para a próxima rota e receber ou atualizar dados assim que retornar da rota:  
251 -  
252 -```dart  
253 -var dados = await Get.to(Pagamento());  
254 -```  
255 -  
256 -Notou que você não precisou usar `context` para fazer nenhuma dessas coisas? Essa é uma das maiores vantagens de usar o gerenciamento de rotas do GetX™. Com isso, você pode executar todos esse métodos de dentro da classe Controller, sem preocupações.  
257 -  
258 -### Mais detalhes sobre gerenciamento de rotas  
259 -  
260 -**GetX™ funciona com rotas nomeadas também! Veja uma explicação mais completa do gerenciamento de rotas [aqui](./documentation/pt_BR/route_management.md)**  
261 -  
262 -### Explicação em video do gerenciamento de rotas  
263 -  
264 -Amateur Coder fez um outro vídeo excelente sobre gerenciamento de rotas! Link: [Complete Getx Navigation](https://www.youtube.com/watch?v=RaqPIoJSTtI)  
265 -  
266 -## Gerenciamento de Dependência  
267 -  
268 -- 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ê.  
269 -  
270 -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:  
271 -  
272 -```dart  
273 -Controller controller = Get.put(Controller()); // Em vez de Controller controller = Controller();  
274 -```  
275 -  
276 -Em vez de instanciar sua classe dentro da classe que você está usando, você está instanciando ele dentro da instância do Get, que vai fazer ele ficar disponível por todo o App para que então você possa usar seu controller (ou uma classe Bloc) normalmente  
277 -  
278 -  
279 -**Dica:** O gerenciamento de dependência Get é desacoplado de outras partes do pacote, então se, por exemplo, seu aplicativo já estiver usando um gerenciador de estado (qualquer um, não importa), você não precisa reescrever tudo, você pode usar esta injeção de dependência sem problemas  
280 -  
281 -```dart  
282 -controller.fetchApi();  
283 -```  
284 -  
285 -Agora, imagine que você navegou por inúmeras rotas e precisa de dados que foram deixados para trás em seu controlador. Você precisaria de um gerenciador de estado combinado com o Provider ou Get_it, correto? Não com Get. Você só precisa pedir ao Get para "procurar" pelo seu controlador, você não precisa de nenhuma dependência adicional para isso:  
286 -  
287 -```dart  
288 -Controller controller = Get.find();  
289 -// Sim, parece Magia, o Get irá descobrir qual é seu controller e irá te entregar.  
290 -// Você pode ter 1 milhão de controllers instanciados, o Get sempre te entregará o controller correto.  
291 -// Apenas se lembre de Tipar seu controller, final controller = Get.find(); por exemplo, não irá funcionar.  
292 -```  
293 -  
294 -E então você será capaz de recuperar os dados do seu controller que foram obtidos anteriormente:  
295 -  
296 -```dart  
297 -Text(controller.textFromApi);  
298 -```  
299 -  
300 -Procurando por `lazyLoading` (carregar somente quando for usar)? Você pode declarar todos os seus controllers e eles só vão ser inicializados e chamados quando alguém precisar. Você pode fazer isso  
301 -  
302 -```dart  
303 -Get.lazyPut<Service>(()=> ApiMock());  
304 -/// ApiMock só será chamado quando alguém usar o Get.find<Service> pela primeira vez  
305 -```  
306 -  
307 -### Mais detalhes sobre gerenciamento de dependências  
308 -  
309 -**Veja uma explicação mais completa do gerenciamento de dependência [aqui](./documentation/pt_BR/dependency_management.md)**  
310 -  
311 -# Utilidades  
312 -  
313 -## Internacionalização  
314 -### Traduções  
315 -Nós mantemos as traduções num simples dictionary map de chave-valor.  
316 -Para adicionar traduções personalizadas, crie uma classe e estenda `Translations`.  
317 -  
318 -```dart  
319 -import 'package:get/get.dart';  
320 -  
321 -class Messages extends Translations {  
322 - @override  
323 - Map<String, Map<String, String>> get keys => {  
324 - 'en_US': {  
325 - 'hello': 'Hello World',  
326 - },  
327 - 'de_DE': {  
328 - 'hello': 'Hallo Welt',  
329 - }  
330 - };  
331 -}  
332 -```  
333 -  
334 -#### Usando traduções  
335 -Basta anexar `.tr` a chave especificada e ela será traduzida, usando o valor atual de `Get.locale` ou `Get.fallbackLocale`.  
336 -```dart  
337 -Text('hello'.tr);  
338 -```  
339 -  
340 -### Localidade  
341 -Passe parâmetros para `GetMaterialApp` definir a localidade e as traduções.  
342 -  
343 -```dart  
344 -return GetMaterialApp(  
345 - translations: Messages(), // suas traduções  
346 - locale: Locale('en', 'US'), // as traduções serão exibidas para esta localidade  
347 - fallbackLocale: Locale('en', 'UK'), // especifica uma localidade em caso de falha na localidade definida  
348 -);  
349 -```  
350 -  
351 -#### Alterar local  
352 -Use `Get.updateLocale(locale)` para atualizar a localidade. As traduções usarão automaticamente a nova localidade e a UI será atualizada.  
353 -```dart  
354 -var locale = Locale('en', 'US');  
355 -Get.updateLocale(locale);  
356 -```  
357 -  
358 -#### Localidade do sistema operacional  
359 -Para ler a localidade do sistema operacional, você pode usar `window.locale`.  
360 -```dart  
361 -import 'dart:ui' as ui;  
362 -  
363 -return GetMaterialApp(  
364 - locale: ui.window.locale,  
365 -);  
366 -```  
367 -  
368 -## Mudar tema (changeTheme)  
369 -  
370 -Por favor não use widget acima do GetMaterialApp para atualizar o tema. Isso pode causar keys duplicadas. Várias pessoas estão acostumadas com o jeito normal de criar um Widget `ThemeProvider` só pra alterar o tema do app, mas isso definitivamente NÃO é necessário com GetX™.  
371 -  
372 -Você pode criar seu tema customizado e simplesmente adicionar dentro do `Get.changeTheme` sem nenhum boilerplate para isso:  
373 -  
374 -```dart  
375 -Get.changeTheme(ThemeData.light())  
376 -```  
377 -  
378 -Se você quer criar algo como um botão que muda o tema com o toque, você pode combinar duas APIs GetX™ pra isso:  
379 -- A API que checa se o tema dark está sendo aplicado;  
380 -- A API de mudar o tema e colocar isso no `onPressed:`  
381 -  
382 -```dart  
383 -Get.changeTheme(Get.isDarkMode ? ThemeData.light() : ThemeData.dark())  
384 -```  
385 -  
386 -Quando o modo Dark está ativado, ele vai trocar pro modo light e vice versa.  
387 -  
388 -Se você quiser saber mais como trocar o tema, você pode seguir esse tutorial no Medium que até ensina persistência do tema usando Get (e SharedPreferences):  
389 -  
390 -- [Dynamic Themes in 3 lines using Get](https://medium.com/swlh/flutter-dynamic-themes-in-3-lines-c3b375f292e3) - Tutorial by [Rod Brown](https://github.com/RodBr).  
391 -  
392 -## Outras APIs avançadas  
393 -  
394 -```dart  
395 -// fornece os arguments da tela atual  
396 -Get.arguments  
397 -  
398 -// fornece os arguments da rota anterior  
399 -Get.previousArguments  
400 -  
401 -// fornece o nome da rota anterior  
402 -Get.previousRoute  
403 -  
404 -// fornece a rota bruta para acessar por exemplo, rawRoute.isFirst()  
405 -Get.rawRoute  
406 -  
407 -// fornece acesso a API de rotas de dentro do GetObserver  
408 -Get.routing  
409 -  
410 -// checa se o snackbar está aberto  
411 -Get.isSnackbarOpen  
412 -  
413 -// checa se o dialog está aberto  
414 -Get.isDialogOpen  
415 -  
416 -// checa se o bottomsheet está aberto  
417 -Get.isBottomSheetOpen  
418 -  
419 -// remove uma rota.  
420 -Get.removeRoute()  
421 -  
422 -// volta repetidamente até o predicate retorne true.  
423 -Get.until()  
424 -  
425 -// vá para a próxima rota e remove todas as rotas  
426 -//anteriores até que o predicate retorne true.  
427 -Get.offUntil()  
428 -  
429 -// vá para a próxima rota nomeada e remove todas as  
430 -//rotas anteriores até que o predicate retorne true.  
431 -Get.offNamedUntil()  
432 -  
433 -// Verifica em que plataforma o app está sendo executado  
434 -// (Esse método é completamente compatível com o FlutterWeb,  
435 -// diferente do método do framework "Platform.isAndroid")  
436 -GetPlatform.isAndroid  
437 -GetPlatform.isIOS  
438 -GetPlatform.isMacOS  
439 -GetPlatform.isWindows  
440 -GetPlatform.isLinux  
441 -GetPlatform.isFuchsia  
442 -  
443 -// Verifica o tipo de dispositivo  
444 -GetPlatform.isMobile  
445 -GetPlatform.isDesktop  
446 -// Todas as plataformas são suportadas de forma independente na web!  
447 -// Você pode saber se está executando dentro de um navegador  
448 -// no Windows, iOS, OSX, Android, etc.  
449 -GetPlatform.isWeb  
450 -  
451 -// Equivalente ao método: MediaQuery.of(context).size.width ou height, mas é imutável.  
452 -// Significa que não irá atualizar mesmo que o tamanho da tela mude (como em navegadores ou app desktop)  
453 -Get.height  
454 -Get.width  
455 -  
456 -// fornece o context da tela em qualquer lugar do seu código.  
457 -Get.context  
458 -  
459 -// fornece o context de snackbar/dialog/bottomsheet em qualquer lugar do seu código.  
460 -Get.contextOverlay  
461 -  
462 -// Obs: os métodos a seguir são extensions do context. Já que se  
463 -// tem acesso ao context em qualquer lugar do código da UI, você pode usar lá  
464 -  
465 -// Se você precisa de um width/height adaptável (como em navegadores em que a janela pode ser redimensionada)  
466 -// você precisa usar 'context'  
467 -context.width  
468 -context.height  
469 -  
470 -// Dá a você agora o poder de definir metade da tela, um terço da dela e assim por diante.  
471 -// Útil para aplicativos responsivos.  
472 -// param dividedBy (double) opcional - default: 1  
473 -// param reducedBy (double) opcional - default: 0  
474 -context.heightTransformer()  
475 -context.widthTransformer()  
476 -  
477 -/// similar a MediaQuery.of(context).size  
478 -context.mediaQuerySize()  
479 -  
480 -/// similar a MediaQuery.of(this).padding  
481 -context.mediaQueryPadding()  
482 -  
483 -/// similar a MediaQuery.of(this).viewPadding  
484 -context.mediaQueryViewPadding()  
485 -  
486 -/// similar a MediaQuery.of(this).viewInsets;  
487 -context.mediaQueryViewInsets()  
488 -  
489 -/// similar a MediaQuery.of(this).orientation;  
490 -context.orientation()  
491 -  
492 -/// verifica se o dispositivo está no modo paisagem  
493 -context.isLandscape()  
494 -  
495 -/// verifica se o dispositivo está no modo retrato  
496 -context.isPortrait()  
497 -  
498 -/// similar a MediaQuery.of(this).devicePixelRatio;  
499 -context.devicePixelRatio()  
500 -  
501 -/// similar a MediaQuery.of(this).textScaleFactor;  
502 -context.textScaleFactor()  
503 -  
504 -/// obtém a menor dimensão (largura ou altura) da tela  
505 -context.mediaQueryShortestSide()  
506 -  
507 -/// retorna True se a largura da tela for maior que 800px  
508 -context.showNavbar()  
509 -  
510 -/// retorna True se a menor dimensão (largura ou altura) da tela for menor que 600px  
511 -context.isPhone()  
512 -  
513 -/// retorna True se a menor dimensão (largura ou altura) da tela for maior ou igual a 600px  
514 -context.isSmallTablet()  
515 -  
516 -/// retorna True se a menor dimensão (largura ou altura) da tela for maior ou igual a 720px  
517 -context.isLargeTablet()  
518 -  
519 -/// retorna True se o dispositivo é um Tablet  
520 -context.isTablet()  
521 -  
522 -/// Retorna um valor de acordo com o tamanho da tela  
523 -/// Os valores possíveis são:  
524 -/// swatch: se a menor dimensão (largura ou altura) da tela for menor que 300px  
525 -/// mobile: se a menor dimensão (largura ou altura) da tela for menor que 600px  
526 -/// tablet: se a menor dimensão (largura ou altura) da tela for menor que 1200px  
527 -/// desktop: se a largura da tela é maior ou iguial a 1200px  
528 -context.responsiveValue<T>()  
529 -```  
530 -  
531 -### Configurações Globais opcionais e configurações manuais  
532 -  
533 -GetMaterialApp configura tudo para você, mas se quiser configurar Get manualmente, você pode.  
534 -  
535 -```dart  
536 -MaterialApp(  
537 - navigatorKey: Get.key,  
538 - navigatorObservers: [GetObserver()],  
539 -);  
540 -```  
541 -  
542 -Você também será capaz de usar seu próprio Middleware dentro do GetObserver, isso não irá influenciar em nada.  
543 -  
544 -```dart  
545 -MaterialApp(  
546 - navigatorKey: Get.key,  
547 - navigatorObservers: [  
548 - GetObserver(MiddleWare.observer) // Aqui  
549 - ],  
550 -);  
551 -```  
552 -  
553 -Você pode criar Configurações Globais para o Get. Apenas adicione `Get.config` ao seu código antes de usar qualquer rota ou faça diretamente no seu GetMaterialApp  
554 -  
555 -```dart  
556 -GetMaterialApp(  
557 - enableLog: true,  
558 - defaultTransition: Transition.fade,  
559 - opaqueRoute: Get.isOpaqueRouteDefault,  
560 - popGesture: Get.isPopGestureEnable,  
561 - transitionDuration: Get.defaultDurationTransition,  
562 - defaultGlobalState: Get.defaultGlobalState,  
563 -);  
564 -Get.config(  
565 - enableLog = true,  
566 - defaultPopGesture = true,  
567 - defaultTransition = Transitions.cupertino  
568 -)  
569 -```  
570 -  
571 -É possível redirecionar todas as mensagens de log do GetX™. Útil quando se tem um package de logging e vc quer que ele lide com todos os logs  
572 -  
573 -```dart  
574 -GetMaterialApp(  
575 - enableLog: true,  
576 - logWriterCallback: localLogWriter,  
577 -);  
578 -  
579 -void localLogWriter(String text, {bool isError = false}) {  
580 - // passage a mensagem para seu package de logging favorito aqui  
581 - // Obs: mesmo que as mensagens de log estejam desativadas  
582 - // com o comando "enableLog: false", as mensagens ainda vão passar por aqui  
583 - // Você precisa checar essa config manualmente aqui se quiser respeitá-la  
584 -}  
585 -```  
586 -  
587 -### Widgets de Estado Local  
588 -  
589 -Esses Widgets permitem que você gerencie um único valor e mantenha o estado efêmero e localmente. Temos versões para Reativo e Simples. Por exemplo, você pode usá-los para alternar obscureText em um `TextField`, talvez criar um painel expansível personalizado ou talvez modificar o índice atual em um `BottomNavigationBar` enquanto altera o conteúdo do corpo em um `Scaffold`.  
590 -  
591 -#### ValueBuilder  
592 -Uma simplificação de `StatefulWidget` que funciona com um callback de `setState` que passa o valor atualizado.  
593 -  
594 -  
595 -```dart  
596 -ValueBuilder<bool>(  
597 - initialValue: false,  
598 - builder: (value, updateFn) => Switch(  
599 - value: value,  
600 - onChanged: updateFn, // mesma assinatura! Você poderia usar ( newValue ) => updateFn( newValue )  
601 - ),  
602 - // se você precisa chamar algo fora do método builder.  
603 - onUpdate: (value) => print("Valor atualizado: $value"),  
604 - onDispose: () => print("Widget desmontado"),  
605 -),  
606 -```  
607 -  
608 -#### ObxValue  
609 -Similar a ValueBuilder, mas esta é a versão Reativa, você passa uma instância Rx (lembra do .obs mágico?) e  
610 -atualiza automaticamente... não é incrível?  
611 -  
612 -```dart  
613 -ObxValue(  
614 - (data) => Switch(  
615 - value: data.value,  
616 - onChanged: data, // Rx tem uma função _callable_! Você poderia usar (flag) => data.value = flag,  
617 - ),  
618 - false.obs,  
619 -),  
620 -```  
621 -  
622 -### Explicação em vídeo sobre Outras Features do GetX  
623 -  
624 -Amateur Coder fez um vídeo incrível sobre utils, storage, bindings e outras features! Link: [GetX Other Features](https://youtu.be/ttQtlX_Q0eU)  
625 -  
626 -  
627 -## Dicas Úteis  
628 -  
629 -`.obs`ervables (também conhecidos como _Rx_ Types) possuem uma grande variedade de métodos e operadores internos.  
630 -  
631 -> É muito comum acreditar que uma propriedade com `.obs` **É** o valor real... mas não se engane!  
632 -> Evitamos a declaração de tipo da variável, porque o compilador do Dart é inteligente o suficiente e o código  
633 -> parece mais limpo, mas:  
634 -  
635 -```dart  
636 -var message = 'Hello world'.obs;  
637 -print( 'Message "$message" é do tipo ${message.runtimeType}');  
638 -```  
639 -  
640 -Mesmo que `message` _imprima_ o valor da string, seu tipo é **RxString**!  
641 -  
642 -Então, você não pode fazer `message.substring( 0, 4 )`.  
643 -Você tem que acessar o `valor` real dentro do _observable_:  
644 -A "maneira" mais usada é utilizando `.value`, mas, você sabia que também pode usar:  
645 -  
646 -```dart  
647 -final name = 'GetX'.obs;  
648 -// apenas "atualiza" o stream, se o valor for diferente do atual.  
649 -name.value = 'Hey';  
650 -  
651 -// Todas as propriedades Rx são "chamáveis" e retorna o novo valor.  
652 -// mas esta abordagem não aceita `null`, a UI não será reconstruída  
653 -name('Hello');  
654 -  
655 -// é como um getter, imprime 'Hello'  
656 -name() ;  
657 -  
658 -/// números:  
659 -  
660 -final count = 0.obs;  
661 -  
662 -// Você pode usar todas as operações não mutáveis ​​de um num!  
663 -count + 1;  
664 -  
665 -// Cuidado! isso só é válido se `count` não for final, mas var  
666 -count += 1;  
667 -  
668 -// Você também pode comparar com os valores:  
669 -count > 2;  
670 -  
671 -/// booleans:  
672 -  
673 -final flag = false.obs;  
674 -  
675 -// mude o valor entre true/false  
676 -flag.toggle();  
677 -  
678 -  
679 -/// todos os tipos:  
680 -  
681 -// Defina `value` como null.  
682 -flag.nil();  
683 -  
684 -// Todas as operações toString() e toJson() são passada para `value`  
685 -print( count ); // chama `toString()` de RxInt  
686 -  
687 -final abc = [0,1,2].obs;  
688 -// Converte o valor em um Array json, imprime RxList  
689 -// Json é suportado por todos os Rx types!  
690 -print('json: ${jsonEncode(abc)}, type: ${abc.runtimeType}');  
691 -  
692 -// RxMap, RxList e RxSet são Rx types especiais, que estendem seus tipos nativos.  
693 -// mas você pode trabalhar com uma lista como uma lista normal, embora seja reativa!  
694 -abc.add(12); // Coloca 12 na lista, e ATUALIZA o stream.  
695 -abc[3]; // como uma lista lê o índice 3.  
696 -  
697 -// a igualdade funciona com o Rx e o value do observável, mas o hashCode é sempre obtido do value  
698 -final number = 12.obs;  
699 -print( number == 12 ); // prints > true  
700 -  
701 -/// Rx Models personalizados:  
702 -  
703 -// toJson(), toString() são transferidos para o filho, para que você possa implementar  
704 -// override neles e imprimir o observável diretamente.  
705 -  
706 -class User {  
707 - String name, last;  
708 - int age;  
709 - User({this.name, this.last, this.age});  
710 -  
711 - @override  
712 - String toString() => '$name $last, $age years old';  
713 -}  
714 -  
715 -final user = User(name: 'John', last: 'Doe', age: 33).obs;  
716 -  
717 -// `user` é "reativo", mas as propriedades dentro NÃO SÃO!  
718 -// Então, se mudarmos alguma variável dentro dele:  
719 -user.value.name = 'Roi';  
720 -// O widget não vai reconstruir!,  
721 -// `Rx` não tem nenhuma notificação quando você muda algo dentro do usuário.  
722 -// Portanto, para classes personalizadas, precisamos "notificar" manualmente a mudança.  
723 -user.refresh();  
724 -  
725 -// ou podemos usar o método `update()`!  
726 -user.update((value){  
727 - value.name='Roi';  
728 -});  
729 -  
730 -print( user ); // Resultado (toString): Roi Doe, 33 years old  
731 -```  
732 -  
733 -#### GetView  
734 -  
735 -Eu amo este Widget, é tão simples, mas tão útil!  
736 -  
737 -É um Widget `const Stateless` que tem um getter `controller` registrado para Controller, só isso.  
738 -  
739 -```dart  
740 -class AwesomeController extends GetxController {  
741 - final String title = 'My Awesome View';  
742 -}  
743 -  
744 -// SEMPRE lembre de passar o `Type` que você usou para registrar seu controlador!  
745 -class AwesomeView extends GetView<AwesomeController> {  
746 - @override  
747 - Widget build(BuildContext context) {  
748 - return Container(  
749 - padding: EdgeInsets.all(20),  
750 - child: Text( controller.title ), // apenas chame `controller.something`  
751 - );  
752 - }  
753 -}  
754 -```  
755 -  
756 -#### GetWidget  
757 -  
758 -A maioria das pessoas não tem ideia sobre este widget, ou confunde totalmente o uso dele.  
759 -O caso de uso é muito raro, mas muito específico: Ele armazena em `cache` um Controller.  
760 -Por causa do _cache_, não pode ser um `const Stateless`.  
761 -  
762 -> Então, quando você precisa armazenar em "cache" um Controller?  
763 -  
764 -Se você usar, uma outra característica "não tão comum" de **GetX™**: `Get.create()`.  
765 -  
766 -`Get.create(()=>Controller())` irá gerar um novo `Controller` cada vez que você chamar  
767 -`Get.find<Controller>()`,  
768 -  
769 -É aí que `GetWidget` brilha... já que você pode usá-lo, por exemplo,  
770 -para manter uma lista de itens Todo. Portanto, se o widget for "reconstruído", ele manterá a mesma instância do controlador.  
771 -  
772 -#### GetxService  
773 -  
774 -Esta classe é como um `GetxController`, ele compartilha o mesmo ciclo de vida ( `onInit()`, `onReady()`, `onClose()`).  
775 -Mas não tem "lógica" dentro dele. Ele apenas notifica o sistema de injeção de dependência do GetX™ de que esta subclasse  
776 -**não pode** ser removida da memória.  
777 -  
778 -Portanto, é muito útil manter seus "Services" sempre acessíveis e ativos com `Get.find()`. Como:  
779 -`ApiService`, `StorageService`, `CacheService`.  
780 -  
781 -```dart  
782 -Future<void> main() async {  
783 - await initServices(); /// Aguarda a inicialização dos Services.  
784 - runApp(SomeApp());  
785 -}  
786 -  
787 -/// É uma jogada inteligente para inicializar seus services antes de executar o aplicativo Flutter,  
788 -/// já que você pode controlar o fluxo de execução (talvez você precise carregar alguma configuração de tema,  
789 -/// apiKey, linguagem definida pelo usuário ... então carregue SettingService antes de executar ApiService.  
790 -/// então GetMaterialApp() não precisa reconstruir e obtém os valores diretamente.  
791 -void initServices() async {  
792 - print('iniciando serviços...');  
793 - /// Aqui é onde você coloca a inicialização de get_storage, hive, shared_pref.  
794 - /// ou checa a conexão, ou o que quer que seja assíncrono.  
795 - await Get.putAsync(() => DbService().init());  
796 - await Get.putAsync(SettingsService()).init();  
797 - print('Todos os serviços iniciados.');  
798 -}  
799 -  
800 -class DbService extends GetxService {  
801 - Future<DbService> init() async {  
802 - print('$runtimeType delays 2 sec');  
803 - await 2.delay();  
804 - print('$runtimeType ready!');  
805 - return this;  
806 - }  
807 -}  
808 -  
809 -class SettingsService extends GetxService {  
810 - void init() async {  
811 - print('$runtimeType delays 1 sec');  
812 - await 1.delay();  
813 - print('$runtimeType ready!');  
814 - }  
815 -}  
816 -```  
817 -  
818 -A única maneira de realmente excluir um `GetxService`, é com o `Get.reset()`, que é como uma  
819 -"hot restart" do seu aplicativo. Portanto, lembre-se, se você precisar de persistência absoluta de uma instância de classe durante  
820 -o ciclo de vida de seu aplicativo, use GetxService.  
821 -  
822 -  
823 -# Breaking Changes da versão 2 para 3  
824 -  
825 -## Tipagem Rx  
826 -  
827 -| Antes | Depois |  
828 -| -------- | ---------- |  
829 -| StringX | `RxString` |  
830 -| IntX | `RxInt` |  
831 -| MapX | `RxMap` |  
832 -| ListX | `RxList` |  
833 -| NumX | `RxNum` |  
834 -| DoubleX | `RxDouble` |  
835 -  
836 -## RxController e GetBuilder se uniram  
837 -  
838 -RxController e GetBuilder agora viraram um só, você não precisa mais memorizar qual controller quer usar, apenas coloque `GetxController`, vai funcionar para os dois gerenciamento de estados  
839 -  
840 -```dart  
841 -//Gerenciador de estado simples  
842 -class Controller extends GetXController {  
843 - String nome = '';  
844 -  
845 - void atualizarNome(String novoNome) {  
846 - nome = novoNome;  
847 - update()  
848 - }  
849 -}  
850 -```  
851 -  
852 -```dart  
853 -class Controller extends GetXController {  
854 - final nome = ''.obs;  
855 -  
856 - // não precisa de um método direto pra atualizar o nome  
857 - // só usar o nome.value  
858 -}  
859 -```  
860 -  
861 -## Rotas nomeadas  
862 -  
863 -Antes:  
864 -  
865 -```dart  
866 -GetMaterialApp(  
867 - namedRoutes: {  
868 - '/': GetRoute(page: Home()),  
869 - }  
870 -)  
871 -```  
872 -  
873 -Agora:  
874 -  
875 -```dart  
876 -GetMaterialApp(  
877 - getPages: [  
878 - GetPage(name: '/', page: () => Home()),  
879 - ]  
880 -)  
881 -```  
882 -  
883 -### Porque essa mudança?  
884 -  
885 -Frequentemente, pode ser necessário decidir qual pagina vai ser mostrada ao usuário a partir de um parâmetro, como um token de login. A forma abordada anteriormente não era flexível, já que não permitia isso.  
886 -  
887 -Inserir a página numa função reduziu significativamente o consumo de RAM, já que as rotas não são alocadas na memória no momento que o app é iniciado e também permite fazer esse tipo de abordagem:  
888 -  
889 -```dart  
890 -  
891 -GetStorage box = GetStorage();  
892 -  
893 -GetMaterialApp(  
894 - getPages: [  
895 - GetPage(name: '/', page:(){  
896 - return box.hasData('token') ? Home() : Login();  
897 - })  
898 - ]  
899 -)  
900 -```  
901 -  
902 -# Por que GetX™?  
903 -  
904 -1- Muitas vezes após uma atualização do Flutter, muitos dos seus packages irão quebrar. As vezes acontecem erros de compilação, muitas vezes aparecem erros que ainda não existem respostas sobre e o desenvolvedor necessita saber de onde o erro veio, rastreá-lo, para só então tentar abrir uma issue no repositório correspondente e ver seu problema resolvido. Get centraliza os principais recursos para o desenvolvimento (Gerência de estado, de dependências e de rotas), permitindo você adicionar um único package em seu pubspec e começar a trabalhar. Após uma atualização do Flutter, a única coisa que você precisa fazer é atualizar a dependencia do Get e começar a trabalhar. Get também resolve problemas de compatibilidade. Quantas vezes uma versão de um package não é compatível com a versão de outro, porque um utiliza uma dependência em uma versão e o outro em outra versão? Essa também não é uma preocupação usando Get, já que tudo está no mesmo package e é totalmente compatível.  
905 -  
906 -2- Flutter é fácil, Flutter é incrível, mas Flutter ainda tem algum boilerplate que pode ser indesejado para maioria dos desenvolvedores, como o Navigator.of(context).push(context, builder[...]. Get simplifica o desenvolvimento. Em vez de escrever 8 linhas de código para apenas chamar uma rota, você pode simplesmente fazer: Get.to(Home()) e pronto, você irá para a próxima página. Urls dinâmicas da web é algo realmente doloroso de fazer com o Flutter atualmente e isso com o GetX™ é estupidamente simples. Gerenciar estados no Flutter e gerenciar dependências também é algo que gera muita discussão, por haver centenas de padrões na pub. Mas não há nada que seja tão fácil quanto adicionar um ".obs" no final de sua variável, colocar o seu widget dentro de um Obx e pronto, todas atualizações daquela variável serão automaticamente atualizadas na tela.  
907 -  
908 -3- Facilidade sem se preocupar com desempenho. O desempenho do Flutter já é incrível, mas imagine que você use um gerenciador de estados e um locator para distribuir suas classes blocs/stores/controllers/ etc. Você deverá chamar manualmente a exclusão daquela dependência quando não precisar dela. Mas já pensou em simplesmente usar seu controlador e quando ele não tivesse mais sendo usado por ninguém, ele simplesmente fosse excluído da memória? É isso que GetX™ faz. Com o SmartManagement, tudo que não está sendo usado é excluído da memória e você não deve se preocupar em nada além de programar. Você terá garantia que está consumindo o mínimo de recursos necessários, sem ao menos ter criado uma lógica para isso.  
909 -  
910 -4- Desacoplamento real. Você já deve ter ouvido o conceito "separar a view da lógica de negócios". Isso não é uma peculiaridade do BLoC, MVC ou MVVM, qualquer outro padrão existente no mercado tem esse conceito. No entanto, muitas vezes esse conceito pode ser mitigado no Flutter por conta do uso do context.  
911 -Se você precisa de context para localizar um InheritedWidget, você precisa disso na view ou passar o context por parâmetro. Eu particularmente acho essa solução muito feia e para trabalhar em equipes teremos sempre uma dependência da lógica de negócios da View. GetX™ é pouco ortodoxo com a abordagem padrão e apesar de não proibir totalmente o uso de StatefulWidgets, InitState e etc, ele tem sempre uma abordagem similar que pode ser mais limpa. Os controllers tem ciclos de vida e quando você precisa fazer uma solicitação APIREST por exemplo, você não depende de nada da view. Você pode usar onInit para iniciar a chamada http e quando os dados chegarem, as variáveis serão preenchidas. Como GetX™ é totalmente reativo (de verdade e trabalha sob streams), assim que os itens forem preenchidos, automaticamente será atualizado na view todos os widgets que usam aquela variável. Isso permite que as pessoas especialistas em UI trabalhem apenas com widgets e não precisem enviar nada para a lógica de negócio além de eventos do usuário (como clicar em um botão), enquanto as pessoas que trabalham com a lógica de negócio ficarão livres para criá-la e testá-la separadamente.  
912 -  
913 -# Comunidade  
914 -  
915 -## Canais da comunidade  
916 -  
917 -GetX™ tem uma comunidade altamente ativa e útil. Se você tiver dúvidas, ou quiser alguma ajuda com relação ao uso deste framework, por favor entre em nossos canais da comunidade, sua dúvida será respondida mais rapidamente, e será o lugar mais adequado. Este repositório é exclusivo para abertura de issues e solicitação de recursos, mas fique à vontade para fazer parte da Comunidade GetX™.  
918 -  
919 -| **Slack (Inglês)** | **Discord (Inglês e Português)** | **Telegram (Português)** |  
920 -| :-------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------- |  
921 -| [![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](https://communityinviter.com/apps/getxworkspace/getx) | [![Discord Shield](https://img.shields.io/discord/722900883784073290.svg?logo=discord)](https://discord.com/invite/9Hpt99N) | [![Telegram](https://img.shields.io/badge/chat-on%20Telegram-blue.svg)](https://t.me/joinchat/PhdbJRmsZNpAqSLJL6bH7g) |  
922 -  
923 -## Como contribuir  
924 -  
925 -_Quer contribuir com o projeto? Teremos o orgulho de destacá-lo como um de nossos colaboradores. Aqui estão alguns pontos onde você pode contribuir e tornar o Get (e Flutter) ainda melhor._  
926 -  
927 -- Ajudando a traduzir o readme para outros idiomas.  
928 -- Adicionando documentação ao readme (muitas funções do Get ainda não foram documentadas).  
929 -- Escreva artigos ou faça vídeos ensinando como usar o Get (eles serão inseridos no Readme e futuramente em nosso Wiki).  
930 -- Fazendo PRs para código/testes.  
931 -- Incluindo novas funções.  
932 -  
933 -Qualquer contribuição é bem-vinda!  
934 -  
935 -  
936 -## Artigos e vídeos  
937 -  
938 -- [Dynamic Themes in 3 lines using GetX™](https://medium.com/swlh/flutter-dynamic-themes-in-3-lines-c3b375f292e3) - Tutorial by [Rod Brown](https://github.com/RodBr). (inglês)  
939 -- [Complete GetX™ Navigation](https://www.youtube.com/watch?v=RaqPIoJSTtI) - Route management video by Amateur Coder. (inglês)  
940 -- [Complete GetX™ State Management](https://www.youtube.com/watch?v=CNpXbeI_slw) - State management video by Amateur Coder. (inglês)  
941 -- [GetX™ Other Features](https://youtu.be/ttQtlX_Q0eU) - Utils, storage, bindings and other features video by Amateur Coder. (inglês)  
942 -- [Firestore User with GetX™ | Todo App](https://www.youtube.com/watch?v=BiV0DcXgk58) - Video by Amateur Coder. (inglês)  
943 -- [Firebase Auth with GetX™ | Todo App](https://www.youtube.com/watch?v=-H-T_BSgfOE) - Video by Amateur Coder. (inglês)  
944 -- [The Flutter GetX™ Ecosystem ~ State Management](https://medium.com/flutter-community/the-flutter-getx-ecosystem-state-management-881c7235511d) - State management by [Aachman Garg](https://github.com/imaachman). (inglês)  
945 -- [GetX™, the all-in-one Flutter package](https://www.youtube.com/watch?v=IYQgtu9TM74) - A brief tutorial covering State Management and Navigation by Thad Carnevalli. (inglês)  
946 -- [Build a To-do List App from scratch using Flutter and GetX™](https://www.youtube.com/watch?v=EcnqFasHf18) - UI + State Management + Storage video by Thad Carnevalli. (inglês)  
947 -- [GetX™ Flutter Firebase Auth Example](https://medium.com/@jeffmcmorris/getx-flutter-firebase-auth-example-b383c1dd1de2) - Article by Jeff McMorris. (inglês)  
1 -/// GetX is an extra-light and powerful multiplatform framework.  
2 -/// It combines high performance state management, intelligent dependency  
3 -/// injection, and route management in a quick and practical way.  
4 -library get;  
5 -  
6 -export 'package:get_core/get_core.dart';  
7 -export 'package:get_state_manager/get_state_manager.dart';  
8 -export 'package:get_instance/get_instance.dart';  
9 -export 'package:get_navigation/get_navigation.dart';  
10 -export 'package:get_utils/get_utils.dart';  
11 -export 'package:get_rx/get_rx.dart';  
12 -export 'package:get_test/get_test.dart';  
1 -/// Get Instance Manager is a modern and intelligent dependency injector  
2 -/// that injects and removes dependencies seasonally.  
3 -library instance_manager;  
4 -  
5 -export 'package:get_instance/get_instance.dart';  
1 -///Get Navigator allows you to navigate routes, open snackbars,  
2 -///dialogs and bottomsheets easily, and without the need for context.  
3 -library route_manager;  
4 -  
5 -export 'package:get_navigation/get_navigation.dart';  
1 -/// Get State Manager is a light, modern and powerful state manager to Flutter  
2 -library state_manager;  
3 -  
4 -export 'package:get_rx/get_rx.dart';  
5 -export 'package:get_state_manager/get_state_manager.dart';  
1 -/// Get utils is a set of tools that allows you to access high-level  
2 -/// APIs and obtain validation tools for Flutter and GetX  
3 -library utils;  
4 -  
5 -export 'package:get_utils/get_utils.dart';  
  1 +/// GetX is an extra-light and powerful multiplatform framework.
  2 +/// It combines high performance state management, intelligent dependency
  3 +/// injection, and route management in a quick and practical way.
  4 +library get;
  5 +
  6 +export 'get_core/get_core.dart';
  7 +export 'get_instance/get_instance.dart';
  8 +export 'get_navigation/get_navigation.dart';
  9 +export 'get_rx/get_rx.dart';
  10 +export 'get_state_manager/get_state_manager.dart';
  11 +export 'get_utils/get_utils.dart';
  1 +library get_core;
  2 +
  3 +export 'src/get_interface.dart';
  4 +export 'src/get_main.dart';
  5 +export 'src/log.dart';
  6 +
  7 +export 'src/smart_management.dart';
  1 +import 'log.dart';
  2 +import 'smart_management.dart';
  3 +
  4 +/// GetInterface allows any auxiliary package to be merged into the "Get"
  5 +/// class through extensions
  6 +abstract class GetInterface {
  7 + SmartManagement smartManagement = SmartManagement.full;
  8 + String reference;
  9 + bool isLogEnable = true;
  10 + LogWriterCallback log = defaultLogWriterCallback;
  11 +}
  1 +import 'get_interface.dart';
  2 +
  3 +///Use to instead of Navigator.push, off instead of Navigator.pushReplacement,
  4 +///offAll instead of Navigator.pushAndRemoveUntil. For named routes just
  5 +///add "named" after them. Example: toNamed, offNamed, and AllNamed.
  6 +///To return to the previous screen, use back().
  7 +///No need to pass any context to Get, just put the name of the route inside
  8 +///the parentheses and the magic will occur.
  9 +class _GetImpl extends GetInterface {}
  10 +
  11 +// ignore: non_constant_identifier_names
  12 +final Get = _GetImpl();
  1 +import 'dart:developer' as developer;
  2 +import 'get_main.dart';
  3 +
  4 +///Voidcallback from logs
  5 +typedef LogWriterCallback = void Function(String text, {bool isError});
  6 +
  7 +/// default logger from GetX
  8 +void defaultLogWriterCallback(String value, {bool isError = false}) {
  9 + if (isError || Get.isLogEnable) developer.log(value, name: 'GETX');
  10 +}
  1 +/// GetX by default disposes unused controllers from memory,
  2 +/// Through different behaviors.
  3 +/// SmartManagement.full
  4 +/// [SmartManagement.full] is the default one. Dispose classes that are
  5 +/// not being used and were not set to be permanent. In the majority
  6 +/// of the cases you will want to keep this config untouched.
  7 +/// If you new to GetX then don't change this.
  8 +/// [SmartManagement.onlyBuilders] only controllers started in init:
  9 +/// or loaded into a Binding with Get.lazyPut() will be disposed. If you use
  10 +/// Get.put() or Get.putAsync() or any other approach, SmartManagement
  11 +/// will not have permissions to exclude this dependency. With the default
  12 +/// behavior, even widgets instantiated with "Get.put" will be removed,
  13 +/// unlike SmartManagement.onlyBuilders.
  14 +/// [SmartManagement.keepFactory]Just like SmartManagement.full,
  15 +/// it will remove it's dependencies when it's not being used anymore.
  16 +/// However, it will keep their factory, which means it will recreate
  17 +/// the dependency if you need that instance again.
  18 +enum SmartManagement {
  19 + full,
  20 + onlyBuilder,
  21 + keepFactory,
  22 +}
  1 +export 'src/bindings_interface.dart';
  2 +export 'src/extension_instance.dart';
  3 +export 'src/get_instance.dart';
  4 +export 'src/lifecycle.dart';
  1 +import 'get_instance.dart';
  2 +
  3 +/// [Bindings] should be extended or implemented.
  4 +/// When using [GetMaterialApp], all [GetPage]s and navigation
  5 +/// methods (like Get.to()) have a [binding] property that takes an
  6 +/// instance of Bindings to manage the
  7 +/// dependencies() (via [Get.put()]) for the Route you are opening.
  8 +// ignore: one_member_abstracts
  9 +abstract class Bindings {
  10 + void dependencies();
  11 +}
  12 +
  13 +/// Simplifies Bindings generation from a single callback.
  14 +/// To avoid the creation of a custom Binding instance per route.
  15 +///
  16 +/// Example:
  17 +/// ```
  18 +/// GetPage(
  19 +/// name: '/',
  20 +/// page: () => Home(),
  21 +/// // This might cause you an error.
  22 +/// // binding: BindingsBuilder(() => Get.put(HomeController())),
  23 +/// binding: BindingsBuilder(() { Get.put(HomeController(); })),
  24 +/// // Using .lazyPut() works fine.
  25 +/// // binding: BindingsBuilder(() => Get.lazyPut(() => HomeController())),
  26 +/// ),
  27 +/// ```
  28 +class BindingsBuilder<T> extends Bindings {
  29 + /// Register your dependencies in the [builder] callback.
  30 + final BindingBuilderCallback builder;
  31 +
  32 + /// Shortcut to register 1 Controller with Get.put(),
  33 + /// Prevents the issue of the fat arrow function with the constructor.
  34 + /// BindingsBuilder(() => Get.put(HomeController())),
  35 + ///
  36 + /// Sample:
  37 + /// ```
  38 + /// GetPage(
  39 + /// name: '/',
  40 + /// page: () => Home(),
  41 + /// binding: BindingsBuilder.put(() => HomeController()),
  42 + /// ),
  43 + /// ```
  44 + factory BindingsBuilder.put(InstanceBuilderCallback<T> builder,
  45 + {String tag, bool permanent = false}) {
  46 + return BindingsBuilder(() => GetInstance()
  47 + .put<T>(null, tag: tag, permanent: permanent, builder: builder));
  48 + }
  49 +
  50 + /// WARNING: don't use `()=> Get.put(Controller())`,
  51 + /// if only passing 1 callback use `BindingsBuilder.put(Controller())`
  52 + /// or `BindingsBuilder(()=> Get.lazyPut(Controller()))`
  53 + BindingsBuilder(this.builder);
  54 +
  55 + @override
  56 + void dependencies() {
  57 + builder();
  58 + }
  59 +}
  60 +
  61 +// abstract class INavigation {}
  62 +// typedef Snack = Function();
  63 +// typedef Modal = Function();
  64 +// typedef Route = Function();
  65 +typedef BindingBuilderCallback = void Function();
  1 +import '../../get_core/src/get_interface.dart';
  2 +
  3 +import 'get_instance.dart';
  4 +
  5 +extension Inst on GetInterface {
  6 + /// Creates a new Instance<S> lazily from the [<S>builder()] callback.
  7 + ///
  8 + /// The first time you call [Get.find()], the [builder()] callback will create
  9 + /// the Instance and persisted as a Singleton (like you would use
  10 + /// [Get.put()]).
  11 + ///
  12 + /// Using [Get.smartManagement] as [SmartManagement.keepFactory] has
  13 + /// the same outcome
  14 + /// as using [fenix:true] :
  15 + /// The internal register of [builder()] will remain in memory to recreate
  16 + /// the Instance if the Instance has been removed with [Get.delete()].
  17 + /// Therefore, future calls to [Get.find()] will return the same Instance.
  18 + ///
  19 + /// If you need to make use of GetxController's life-cycle
  20 + /// ([onInit(), onStart(), onClose()])
  21 + /// [fenix] is a great choice to mix with [GetBuilder()] and [GetX()] widgets,
  22 + /// and/or [GetMaterialApp] Navigation.
  23 + ///
  24 + /// You could use [Get.lazyPut(fenix:true)] in your app's [main()] instead of
  25 + /// [Bindings()] for each [GetPage].
  26 + /// And the memory management will be similar.
  27 + ///
  28 + /// Subsequent calls to [Get.lazyPut()] with the same parameters
  29 + /// (<[S]> and optionally [tag] will **not** override the original).
  30 + void lazyPut<S>(InstanceBuilderCallback<S> builder,
  31 + {String tag, bool fenix = false}) {
  32 + GetInstance().lazyPut<S>(builder, tag: tag, fenix: fenix);
  33 + }
  34 +
  35 + /// async version of [Get.put()].
  36 + /// Awaits for the resolution of the Future from [builder()] parameter and
  37 + /// stores the Instance returned.
  38 + Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder,
  39 + {String tag, bool permanent = false}) async =>
  40 + GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent);
  41 +
  42 + /// Creates a new Class Instance [S] from the builder callback[S].
  43 + /// Every time [find]<[S]>() is used, it calls the builder method to generate
  44 + /// a new Instance [S].
  45 + /// It also registers each [instance.onClose()] with the current
  46 + /// Route [GetConfig.currentRoute] to keep the lifecycle active.
  47 + /// Is important to know that the instances created are only stored per Route.
  48 + /// So, if you call `Get.delete<T>()` the "instance factory" used in this
  49 + /// method ([Get.create<T>()]) will be removed, but NOT the instances
  50 + /// already created by it.
  51 + /// Uses `tag` as the other methods.
  52 + ///
  53 + /// Example:
  54 + ///
  55 + /// ```create(() => Repl());
  56 + /// Repl a = find();
  57 + /// Repl b = find();
  58 + /// print(a==b); (false)```
  59 + void create<S>(InstanceBuilderCallback<S> builder,
  60 + {String tag, bool permanent = true}) =>
  61 + GetInstance().create<S>(builder, tag: tag, permanent: permanent);
  62 +
  63 + /// Finds a Instance of the required Class <[S]>(or [tag])
  64 + /// In the case of using [Get.create()], it will generate an Instance
  65 + /// each time you call [Get.find()].
  66 + S find<S>({String tag}) => GetInstance().find<S>(tag: tag);
  67 +
  68 + /// Injects an [Instance<S>] in memory.
  69 + ///
  70 + /// No need to define the generic type <[S]> as it's inferred
  71 + /// from the [dependency] parameter.
  72 + ///
  73 + /// - [dependency] The Instance to be injected.
  74 + /// - [tag] optionally, use a [tag] as an "id" to create multiple records
  75 + /// of the same Type<[S]> the [tag] does **not** conflict with the same tags
  76 + /// used by other [dependencies] Types.
  77 + /// - [permanent] keeps the Instance in memory and persist it,
  78 + /// not following [Get.smartManagement]
  79 + /// rules. Although, can be removed by [GetInstance.reset()]
  80 + /// and [Get.delete()]
  81 + /// - [builder] If defined, the [dependency] must be returned from here
  82 + S put<S>(S dependency,
  83 + {String tag,
  84 + bool permanent = false,
  85 + InstanceBuilderCallback<S> builder}) =>
  86 + GetInstance()
  87 + .put<S>(dependency, tag: tag, permanent: permanent, builder: builder);
  88 +
  89 + /// Clears all registered instances (and/or tags).
  90 + /// Even the persistent ones.
  91 + ///
  92 + /// - [clearFactory] clears the callbacks registered by [Get.lazyPut()]
  93 + /// - [clearRouteBindings] clears Instances associated with Routes when using
  94 + /// [GetMaterialApp].
  95 + bool reset({bool clearFactory = true, bool clearRouteBindings = true}) =>
  96 + GetInstance().reset(
  97 + clearFactory: clearFactory, clearRouteBindings: clearRouteBindings);
  98 +
  99 + /// Deletes the Instance<[S]>, cleaning the memory and closes any open
  100 + /// controllers ([DisposableInterface]).
  101 + ///
  102 + /// - [tag] Optional "tag" used to register the Instance
  103 + /// - [force] Will delete an Instance even if marked as [permanent].
  104 + Future<bool> delete<S>({String tag, bool force = false}) async =>
  105 + GetInstance().delete<S>(tag: tag, force: force);
  106 +
  107 + /// Checks if a Class Instance<[S]> (or [tag]) is registered in memory.
  108 + /// - [tag] optional, if you use a [tag] to register the Instance.
  109 + bool isRegistered<S>({String tag}) => GetInstance().isRegistered<S>(tag: tag);
  110 +
  111 + /// Checks if an Instance<[S]> (or [tag]) returned from a factory builder
  112 + /// [Get.lazyPut()], is registered in memory.
  113 + /// - [tag] optional, if you use a [tag] to register the Instance.
  114 + bool isPrepared<S>({String tag}) => GetInstance().isPrepared<S>(tag: tag);
  115 +}
  1 +import 'dart:async';
  2 +import 'dart:collection';
  3 +import '../../get_core/get_core.dart';
  4 +
  5 +import 'lifecycle.dart';
  6 +
  7 +class GetInstance {
  8 + factory GetInstance() => _getInstance ??= GetInstance._();
  9 +
  10 + const GetInstance._();
  11 +
  12 + static GetInstance _getInstance;
  13 +
  14 + /// Holds references to every registered Instance when using
  15 + /// [Get.put()]
  16 + static final Map<String, _InstanceBuilderFactory> _singl = {};
  17 +
  18 + /// Holds a reference to every registered callback when using
  19 + /// [Get.lazyPut()]
  20 + static final Map<String, _Lazy> _factory = {};
  21 +
  22 + /// Holds a reference to [Get.reference] when the Instance was
  23 + /// created to manage the memory.
  24 + static final Map<String, String> _routesKey = {};
  25 +
  26 + /// Stores the onClose() references of instances created with [Get.create()]
  27 + /// using the [Get.reference].
  28 + /// Experimental feature to keep the lifecycle and memory management with
  29 + /// non-singleton instances.
  30 + static final Map<String, HashSet<Function>> _routesByCreate = {};
  31 +
  32 + /// Creates a new Instance<S> lazily from the [<S>builder()] callback.
  33 + ///
  34 + /// The first time you call [Get.find()], the [builder()] callback will create
  35 + /// the Instance and persisted as a Singleton (like you would
  36 + /// use [Get.put()]).
  37 + ///
  38 + /// Using [Get.smartManagement] as [SmartManagement.keepFactory] has
  39 + /// the same outcome as using [fenix:true] :
  40 + /// The internal register of [builder()] will remain in memory to recreate
  41 + /// the Instance if the Instance has been removed with [Get.delete()].
  42 + /// Therefore, future calls to [Get.find()] will return the same Instance.
  43 + ///
  44 + /// If you need to make use of GetxController's life-cycle
  45 + /// ([onInit(), onStart(), onClose()]) [fenix] is a great choice to mix with
  46 + /// [GetBuilder()] and [GetX()] widgets, and/or [GetMaterialApp] Navigation.
  47 + ///
  48 + /// You could use [Get.lazyPut(fenix:true)] in your app's [main()] instead
  49 + /// of [Bindings()] for each [GetPage].
  50 + /// And the memory management will be similar.
  51 + ///
  52 + /// Subsequent calls to [Get.lazyPut()] with the same parameters
  53 + /// (<[S]> and optionally [tag] will **not** override the original).
  54 + void lazyPut<S>(
  55 + InstanceBuilderCallback<S> builder, {
  56 + String tag,
  57 + bool fenix = false,
  58 + }) {
  59 + final key = _getKey(S, tag);
  60 + _factory.putIfAbsent(key, () => _Lazy(builder, fenix));
  61 + }
  62 +
  63 + /// async version of [Get.put()].
  64 + /// Awaits for the resolution of the Future from [builder()] parameter and
  65 + /// stores the Instance returned.
  66 + Future<S> putAsync<S>(
  67 + AsyncInstanceBuilderCallback<S> builder, {
  68 + String tag,
  69 + bool permanent = false,
  70 + }) async {
  71 + return put<S>(await builder(), tag: tag, permanent: permanent);
  72 + }
  73 +
  74 + /// Injects an instance <[S]> in memory to be globally accessible.
  75 + ///
  76 + /// No need to define the generic type <[S]> as it's inferred from
  77 + /// the [dependency]
  78 + ///
  79 + /// - [dependency] The Instance to be injected.
  80 + /// - [tag] optionally, use a [tag] as an "id" to create multiple records of
  81 + /// the same Type<[S]>
  82 + /// - [permanent] keeps the Instance in memory, not following
  83 + /// [Get.smartManagement] rules.
  84 + S put<S>(
  85 + S dependency, {
  86 + String tag,
  87 + bool permanent = false,
  88 + InstanceBuilderCallback<S> builder,
  89 + }) {
  90 + _insert(
  91 + isSingleton: true,
  92 + name: tag,
  93 + permanent: permanent,
  94 + builder: builder ?? (() => dependency));
  95 + return find<S>(tag: tag);
  96 + }
  97 +
  98 + /// Creates a new Class Instance [S] from the builder callback[S].
  99 + /// Every time [find]<[S]>() is used, it calls the builder method to generate
  100 + /// a new Instance [S].
  101 + /// It also registers each [instance.onClose()] with the current
  102 + /// Route [Get.reference] to keep the lifecycle active.
  103 + /// Is important to know that the instances created are only stored per Route.
  104 + /// So, if you call `Get.delete<T>()` the "instance factory" used in this
  105 + /// method ([Get.create<T>()]) will be removed, but NOT the instances
  106 + /// already created by it.
  107 + ///
  108 + /// Example:
  109 + ///
  110 + /// ```create(() => Repl());
  111 + /// Repl a = find();
  112 + /// Repl b = find();
  113 + /// print(a==b); (false)```
  114 + void create<S>(
  115 + InstanceBuilderCallback<S> builder, {
  116 + String tag,
  117 + bool permanent = true,
  118 + }) {
  119 + _insert(
  120 + isSingleton: false, name: tag, builder: builder, permanent: permanent);
  121 + }
  122 +
  123 + /// Injects the Instance [S] builder into the [_singleton] HashMap.
  124 + void _insert<S>({
  125 + bool isSingleton,
  126 + String name,
  127 + bool permanent = false,
  128 + InstanceBuilderCallback<S> builder,
  129 + }) {
  130 + assert(builder != null);
  131 + final key = _getKey(S, name);
  132 + _singl.putIfAbsent(
  133 + key,
  134 + () =>
  135 + _InstanceBuilderFactory<S>(isSingleton, builder, permanent, false));
  136 + }
  137 +
  138 + /// Clears from memory registered Instances associated with [routeName] when
  139 + /// using [Get.smartManagement] as [SmartManagement.full] or
  140 + /// [SmartManagement.keepFactory]
  141 + /// Meant for internal usage of [GetPageRoute] and [GetDialogRoute]
  142 + void removeDependencyByRoute(String routeName) {
  143 + final keysToRemove = <String>[];
  144 + _routesKey.forEach((key, value) {
  145 + if (value == routeName) {
  146 + keysToRemove.add(key);
  147 + }
  148 + });
  149 +
  150 + /// Removes [Get.create()] instances registered in [routeName].
  151 + if (_routesByCreate.containsKey(routeName)) {
  152 + for (final onClose in _routesByCreate[routeName]) {
  153 + // assure the [DisposableInterface] instance holding a reference
  154 + // to [onClose()] wasn't disposed.
  155 + if (onClose != null) {
  156 + onClose();
  157 + }
  158 + }
  159 + _routesByCreate[routeName].clear();
  160 + _routesByCreate.remove(routeName);
  161 + }
  162 +
  163 + for (final element in keysToRemove) {
  164 + delete(key: element);
  165 + }
  166 +
  167 + for (final element in keysToRemove) {
  168 + _routesKey?.remove(element);
  169 + }
  170 + keysToRemove.clear();
  171 + }
  172 +
  173 + /// Initializes the dependencies for a Class Instance [S] (or tag),
  174 + /// If its a Controller, it starts the lifecycle process.
  175 + /// Optionally associating the current Route to the lifetime of the instance,
  176 + /// if [Get.smartManagement] is marked as [SmartManagement.full] or
  177 + /// [Get.keepFactory]
  178 + /// Only flags `isInit` if it's using `Get.create()`
  179 + /// (not for Singletons access).
  180 + /// Returns the instance if not initialized, required for Get.create() to
  181 + /// work properly.
  182 + S _initDependencies<S>({String name}) {
  183 + final key = _getKey(S, name);
  184 + final isInit = _singl[key].isInit;
  185 + S i;
  186 + if (!isInit) {
  187 + i = _startController<S>(tag: name);
  188 + if (_singl[key].isSingleton) {
  189 + _singl[key].isInit = true;
  190 + if (Get.smartManagement != SmartManagement.onlyBuilder) {
  191 + _registerRouteInstance<S>(tag: name);
  192 + }
  193 + }
  194 + }
  195 + return i;
  196 + }
  197 +
  198 + /// Links a Class instance [S] (or [tag]) to the current route.
  199 + /// Requires usage of [GetMaterialApp].
  200 + void _registerRouteInstance<S>({String tag}) {
  201 + _routesKey.putIfAbsent(_getKey(S, tag), () => Get.reference);
  202 + }
  203 +
  204 + /// Finds and returns a Instance<[S]> (or [tag]) without further processing.
  205 + S findByType<S>(Type type, {String tag}) {
  206 + final key = _getKey(type, tag);
  207 + return _singl[key].getDependency() as S;
  208 + }
  209 +
  210 + /// Initializes the controller
  211 + S _startController<S>({String tag}) {
  212 + final key = _getKey(S, tag);
  213 + final i = _singl[key].getDependency() as S;
  214 + if (i is GetLifeCycle) {
  215 + if (i.onStart != null) {
  216 + i.onStart();
  217 + Get.log('"$key" has been initialized');
  218 + }
  219 + if (!_singl[key].isSingleton && i.onClose != null) {
  220 + _routesByCreate[Get.reference] ??= HashSet<Function>();
  221 + _routesByCreate[Get.reference].add(i.onClose);
  222 + }
  223 + }
  224 + return i;
  225 + }
  226 +
  227 + S putOrFind<S>(InstanceBuilderCallback<S> dep, {String tag}) {
  228 + final key = _getKey(S, tag);
  229 +
  230 + if (_singl.containsKey(key)) {
  231 + return _singl[key].getDependency() as S;
  232 + } else {
  233 + if (_factory.containsKey(key)) {
  234 + final _value = put<S>((_factory[key].builder() as S), tag: tag);
  235 +
  236 + if (Get.smartManagement != SmartManagement.keepFactory) {
  237 + if (!_factory[key].fenix) {
  238 + _factory.remove(key);
  239 + }
  240 + }
  241 + return _value;
  242 + }
  243 +
  244 + return GetInstance().put(dep(), tag: tag);
  245 + }
  246 + }
  247 +
  248 + /// Finds the registered type <[S]> (or [tag])
  249 + /// In case of using Get.[create] to register a type <[S]> or [tag],
  250 + /// it will create an instance each time you call [find].
  251 + /// If the registered type <[S]> (or [tag]) is a Controller,
  252 + /// it will initialize it's lifecycle.
  253 + S find<S>({String tag}) {
  254 + final key = _getKey(S, tag);
  255 + if (isRegistered<S>(tag: tag)) {
  256 + if (_singl[key] == null) {
  257 + if (tag == null) {
  258 + throw 'Class "$S" is not registered';
  259 + } else {
  260 + throw 'Class "$S" with tag "$tag" is not registered';
  261 + }
  262 + }
  263 +
  264 + /// although dirty solution, the lifecycle starts inside
  265 + /// `initDependencies`, so we have to return the instance from there
  266 + /// to make it compatible with `Get.create()`.
  267 + final i = _initDependencies<S>(name: tag);
  268 + return i ?? _singl[key].getDependency() as S;
  269 + } else {
  270 + if (!_factory.containsKey(key)) {
  271 + // ignore: lines_longer_than_80_chars
  272 + throw '"$S" not found. You need to call "Get.put($S())" or "Get.lazyPut(()=>$S())"';
  273 + }
  274 +
  275 + Get.log('Lazy instance "$S" created');
  276 + final _value = put<S>(_factory[key].builder() as S, tag: tag);
  277 + _initDependencies<S>(name: tag);
  278 +
  279 + if (Get.smartManagement != SmartManagement.keepFactory &&
  280 + !_factory[key].fenix) {
  281 + _factory.remove(key);
  282 + }
  283 +
  284 + return _value;
  285 + }
  286 + }
  287 +
  288 + /// Generates the key based on [type] (and optionally a [name])
  289 + /// to register an Instance Builder in the hashmap.
  290 + String _getKey(Type type, String name) {
  291 + return name == null ? type.toString() : type.toString() + name;
  292 + }
  293 +
  294 + /// Clears all registered instances (and/or tags).
  295 + /// Even the persistent ones.
  296 + ///
  297 + /// [clearFactory] clears the callbacks registered by [lazyPut]
  298 + /// [clearRouteBindings] clears Instances associated with routes.
  299 + ///
  300 + bool reset({bool clearFactory = true, bool clearRouteBindings = true}) {
  301 + if (clearFactory) _factory.clear();
  302 + if (clearRouteBindings) _routesKey.clear();
  303 + _singl.clear();
  304 + return true;
  305 + }
  306 +
  307 + /// Delete registered Class Instance [S] (or [tag]) and, closes any open
  308 + /// controllers [DisposableInterface], cleans up the memory
  309 + ///
  310 + /// /// Deletes the Instance<[S]>, cleaning the memory.
  311 + // ///
  312 + // /// - [tag] Optional "tag" used to register the Instance
  313 + // /// - [key] For internal usage, is the processed key used to register
  314 + // /// the Instance. **don't use** it unless you know what you are doing.
  315 +
  316 + /// Deletes the Instance<[S]>, cleaning the memory and closes any open
  317 + /// controllers ([DisposableInterface]).
  318 + ///
  319 + /// - [tag] Optional "tag" used to register the Instance
  320 + /// - [key] For internal usage, is the processed key used to register
  321 + /// the Instance. **don't use** it unless you know what you are doing.
  322 + /// - [force] Will delete an Instance even if marked as [permanent].
  323 + bool delete<S>({String tag, String key, bool force = false}) {
  324 + // return _queue.secure<bool>(() {
  325 + return _delete<S>(tag: tag, key: key, force: force);
  326 + // });
  327 + }
  328 +
  329 + bool _delete<S>({String tag, String key, bool force = false}) {
  330 + final newKey = key ?? _getKey(S, tag);
  331 +
  332 + if (!_singl.containsKey(newKey)) {
  333 + Get.log('Instance "$newKey" already removed.', isError: true);
  334 + return false;
  335 + }
  336 +
  337 + final builder = _singl[newKey];
  338 + if (builder.permanent && !force) {
  339 + Get.log(
  340 + // ignore: lines_longer_than_80_chars
  341 + '"$newKey" has been marked as permanent, SmartManagement is not authorized to delete it.',
  342 + isError: true,
  343 + );
  344 + return false;
  345 + }
  346 + final i = builder.dependency;
  347 +
  348 + if (i is GetxServiceMixin && !force) {
  349 + return false;
  350 + }
  351 + if (i is GetLifeCycle) {
  352 + i.onClose();
  353 + Get.log('"$newKey" onClose() called');
  354 + }
  355 +
  356 + _singl.removeWhere((oldKey, value) => (oldKey == newKey));
  357 + if (_singl.containsKey(newKey)) {
  358 + Get.log('Error removing object "$newKey"', isError: true);
  359 + } else {
  360 + Get.log('"$newKey" deleted from memory');
  361 + }
  362 + // _routesKey?.remove(key);
  363 + return true;
  364 + }
  365 +
  366 + /// Check if a Class Instance<[S]> (or [tag]) is registered in memory.
  367 + /// - [tag] is optional, if you used a [tag] to register the Instance.
  368 + bool isRegistered<S>({String tag}) => _singl.containsKey(_getKey(S, tag));
  369 +
  370 + /// Checks if a lazy factory callback ([Get.lazyPut()] that returns an
  371 + /// Instance<[S]> is registered in memory.
  372 + /// - [tag] is optional, if you used a [tag] to register the lazy Instance.
  373 + bool isPrepared<S>({String tag}) => _factory.containsKey(_getKey(S, tag));
  374 +}
  375 +
  376 +typedef InstanceBuilderCallback<S> = S Function();
  377 +
  378 +typedef AsyncInstanceBuilderCallback<S> = Future<S> Function();
  379 +
  380 +/// Internal class to register instances with Get.[put]<[S]>().
  381 +class _InstanceBuilderFactory<S> {
  382 + /// Marks the Builder as a single instance.
  383 + /// For reusing [dependency] instead of [builderFunc]
  384 + bool isSingleton;
  385 +
  386 + /// Stores the actual object instance when [isSingleton]=true.
  387 + S dependency;
  388 +
  389 + /// Generates (and regenerates) the instance when [isSingleton]=false.
  390 + /// Usually used by factory methods
  391 + InstanceBuilderCallback<S> builderFunc;
  392 +
  393 + /// Flag to persist the instance in memory,
  394 + /// without considering [Get.smartManagement]
  395 + bool permanent = false;
  396 +
  397 + bool isInit = false;
  398 +
  399 + _InstanceBuilderFactory(
  400 + this.isSingleton,
  401 + this.builderFunc,
  402 + this.permanent,
  403 + this.isInit,
  404 + );
  405 +
  406 + /// Gets the actual instance by it's [builderFunc] or the persisted instance.
  407 + S getDependency() {
  408 + return isSingleton ? dependency ??= builderFunc() : builderFunc();
  409 + }
  410 +}
  411 +
  412 +/// Internal class to register a future instance with [lazyPut],
  413 +/// keeps a reference to the callback to be called.
  414 +class _Lazy {
  415 + bool fenix;
  416 + InstanceBuilderCallback builder;
  417 +
  418 + _Lazy(this.builder, this.fenix);
  419 +}
  1 +/// Special callable class to keep the contract of a regular method, and avoid
  2 +/// overrides if you extend the class that uses it, as Dart has no final
  3 +/// methods.
  4 +/// Used in [DisposableInterface] to avoid the danger of overriding onStart.
  5 +///
  6 +class _InternalFinalCallback<T> {
  7 + T Function() callback;
  8 +
  9 + _InternalFinalCallback();
  10 +
  11 + T call() => callback.call();
  12 +}
  13 +
  14 +abstract class GetLifeCycle {
  15 + /// Called at the exact moment the widget is allocated in memory.
  16 + /// It uses an internal "callable" type, to avoid any @overrides in subclases.
  17 + /// This method should be internal and is required to define the
  18 + /// lifetime cycle of the subclass.
  19 + final onStart = _InternalFinalCallback<void>();
  20 +
  21 + /// Called immediately after the widget is allocated in memory.
  22 + /// You might use this to initialize something for the controller.
  23 + void onInit() {}
  24 +
  25 + /// Called 1 frame after onInit(). It is the perfect place to enter
  26 + /// navigation events, like snackbar, dialogs, or a new route, or
  27 + /// async request.
  28 + void onReady() {}
  29 +
  30 + /// Called before [onDelete] method. [onClose] might be used to
  31 + /// dispose resources used by the controller. Like closing events,
  32 + /// or streams before the controller is destroyed.
  33 + /// Or dispose objects that can potentially create some memory leaks,
  34 + /// like TextEditingControllers, AnimationControllers.
  35 + /// Might be useful as well to persist some data on disk.
  36 + void onClose() {}
  37 +}
  38 +
  39 +/// Allow track difference between GetxServices and GetxControllers
  40 +mixin GetxServiceMixin {}
  1 +library get_navigation;
  2 +
  3 +export 'src/bottomsheet/bottomsheet.dart';
  4 +export 'src/extension_navigation.dart';
  5 +export 'src/root/root_widget.dart';
  6 +export 'src/routes/custom_transition.dart';
  7 +export 'src/routes/default_route.dart';
  8 +export 'src/routes/default_route.dart';
  9 +export 'src/routes/get_route.dart';
  10 +export 'src/routes/observers/route_observer.dart';
  11 +export 'src/routes/transitions_type.dart';
  12 +export 'src/snackbar/snack.dart';
  13 +export 'src/snackbar/snack_route.dart';
  1 +import 'package:flutter/material.dart';
  2 +
  3 +class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
  4 + GetModalBottomSheetRoute({
  5 + this.builder,
  6 + this.theme,
  7 + this.barrierLabel,
  8 + this.backgroundColor,
  9 + this.isPersistent,
  10 + this.elevation,
  11 + this.shape,
  12 + this.removeTop = true,
  13 + this.clipBehavior,
  14 + this.modalBarrierColor,
  15 + this.isDismissible = true,
  16 + this.enableDrag = true,
  17 + @required this.isScrollControlled,
  18 + RouteSettings settings,
  19 + this.enterBottomSheetDuration = const Duration(milliseconds: 250),
  20 + this.exitBottomSheetDuration = const Duration(milliseconds: 200),
  21 + }) : assert(isScrollControlled != null),
  22 + name = "BOTTOMSHEET: ${builder.hashCode}",
  23 + assert(isDismissible != null),
  24 + assert(enableDrag != null),
  25 + super(settings: settings);
  26 + final bool isPersistent;
  27 + final WidgetBuilder builder;
  28 + final ThemeData theme;
  29 + final bool isScrollControlled;
  30 + final Color backgroundColor;
  31 + final double elevation;
  32 + final ShapeBorder shape;
  33 + final Clip clipBehavior;
  34 + final Color modalBarrierColor;
  35 + final bool isDismissible;
  36 + final bool enableDrag;
  37 + final String name;
  38 + final Duration enterBottomSheetDuration;
  39 + final Duration exitBottomSheetDuration;
  40 + // remove safearea from top
  41 + final bool removeTop;
  42 +
  43 + @override
  44 + Duration get transitionDuration => Duration(milliseconds: 700);
  45 +
  46 + @override
  47 + bool get barrierDismissible => isDismissible;
  48 +
  49 + @override
  50 + final String barrierLabel;
  51 +
  52 + @override
  53 + Color get barrierColor => modalBarrierColor ?? Colors.black54;
  54 +
  55 + AnimationController _animationController;
  56 +
  57 + @override
  58 + AnimationController createAnimationController() {
  59 + assert(_animationController == null);
  60 + _animationController =
  61 + BottomSheet.createAnimationController(navigator.overlay);
  62 + _animationController.duration = enterBottomSheetDuration;
  63 + _animationController.reverseDuration = exitBottomSheetDuration;
  64 + return _animationController;
  65 + }
  66 +
  67 + @override
  68 + Widget buildPage(BuildContext context, Animation<double> animation,
  69 + Animation<double> secondaryAnimation) {
  70 + final sheetTheme =
  71 + theme?.bottomSheetTheme ?? Theme.of(context).bottomSheetTheme;
  72 + // By definition, the bottom sheet is aligned to the bottom of the page
  73 + // and isn't exposed to the top padding of the MediaQuery.
  74 + Widget bottomSheet = MediaQuery.removePadding(
  75 + context: context,
  76 + removeTop: removeTop,
  77 + child: Padding(
  78 + padding:
  79 + EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
  80 + child: _GetModalBottomSheet<T>(
  81 + route: this,
  82 + backgroundColor: backgroundColor ??
  83 + sheetTheme?.modalBackgroundColor ??
  84 + sheetTheme?.backgroundColor,
  85 + elevation:
  86 + elevation ?? sheetTheme?.modalElevation ?? sheetTheme?.elevation,
  87 + shape: shape,
  88 + clipBehavior: clipBehavior,
  89 + isScrollControlled: isScrollControlled,
  90 + enableDrag: enableDrag,
  91 + ),
  92 + ),
  93 + );
  94 + if (theme != null) bottomSheet = Theme(data: theme, child: bottomSheet);
  95 + return bottomSheet;
  96 + }
  97 +}
  98 +
  99 +class _GetModalBottomSheet<T> extends StatefulWidget {
  100 + const _GetModalBottomSheet({
  101 + Key key,
  102 + this.route,
  103 + this.backgroundColor,
  104 + this.elevation,
  105 + this.shape,
  106 + this.clipBehavior,
  107 + this.isScrollControlled = false,
  108 + this.enableDrag = true,
  109 + this.isPersistent = false,
  110 + }) : assert(isScrollControlled != null),
  111 + assert(enableDrag != null),
  112 + super(key: key);
  113 + final bool isPersistent;
  114 + final GetModalBottomSheetRoute<T> route;
  115 + final bool isScrollControlled;
  116 + final Color backgroundColor;
  117 + final double elevation;
  118 + final ShapeBorder shape;
  119 + final Clip clipBehavior;
  120 + final bool enableDrag;
  121 +
  122 + @override
  123 + _GetModalBottomSheetState<T> createState() => _GetModalBottomSheetState<T>();
  124 +}
  125 +
  126 +class _GetModalBottomSheetState<T> extends State<_GetModalBottomSheet<T>> {
  127 + String _getRouteLabel(MaterialLocalizations localizations) {
  128 + if ((Theme.of(context).platform == TargetPlatform.android) ||
  129 + (Theme.of(context).platform == TargetPlatform.fuchsia)) {
  130 + return localizations.dialogLabel;
  131 + } else {
  132 + return '';
  133 + }
  134 + }
  135 +
  136 + @override
  137 + Widget build(BuildContext context) {
  138 + assert(debugCheckHasMediaQuery(context));
  139 + assert(debugCheckHasMaterialLocalizations(context));
  140 + final mediaQuery = MediaQuery.of(context);
  141 + final localizations = MaterialLocalizations.of(context);
  142 + final routeLabel = _getRouteLabel(localizations);
  143 +
  144 + return AnimatedBuilder(
  145 + animation: widget.route.animation,
  146 + builder: (context, child) {
  147 + // Disable the initial animation when accessible navigation is on so
  148 + // that the semantics are added to the tree at the correct time.
  149 + final animationValue = mediaQuery.accessibleNavigation
  150 + ? 1.0
  151 + : widget.route.animation.value;
  152 + return Semantics(
  153 + scopesRoute: true,
  154 + namesRoute: true,
  155 + label: routeLabel,
  156 + explicitChildNodes: true,
  157 + child: ClipRect(
  158 + child: CustomSingleChildLayout(
  159 + delegate: _GetModalBottomSheetLayout(
  160 + animationValue, widget.isScrollControlled),
  161 + child: widget.isPersistent == false
  162 + ? BottomSheet(
  163 + animationController: widget.route._animationController,
  164 + onClosing: () {
  165 + if (widget.route.isCurrent) {
  166 + Navigator.pop(context);
  167 + }
  168 + },
  169 + builder: widget.route.builder,
  170 + backgroundColor: widget.backgroundColor,
  171 + elevation: widget.elevation,
  172 + shape: widget.shape,
  173 + clipBehavior: widget.clipBehavior,
  174 + enableDrag: widget.enableDrag,
  175 + )
  176 + : Scaffold(
  177 + bottomSheet: BottomSheet(
  178 + animationController:
  179 + widget.route._animationController,
  180 + onClosing: () {
  181 + // if (widget.route.isCurrent) {
  182 + // Navigator.pop(context);
  183 + // }
  184 + },
  185 + builder: widget.route.builder,
  186 + backgroundColor: widget.backgroundColor,
  187 + elevation: widget.elevation,
  188 + shape: widget.shape,
  189 + clipBehavior: widget.clipBehavior,
  190 + enableDrag: widget.enableDrag,
  191 + ),
  192 + )),
  193 + ),
  194 + );
  195 + },
  196 + );
  197 + }
  198 +}
  199 +
  200 +class _GetPerModalBottomSheet<T> extends StatefulWidget {
  201 + const _GetPerModalBottomSheet({
  202 + Key key,
  203 + this.route,
  204 + this.isPersistent,
  205 + this.backgroundColor,
  206 + this.elevation,
  207 + this.shape,
  208 + this.clipBehavior,
  209 + this.isScrollControlled = false,
  210 + this.enableDrag = true,
  211 + }) : assert(isScrollControlled != null),
  212 + assert(enableDrag != null),
  213 + super(key: key);
  214 + final bool isPersistent;
  215 + final GetModalBottomSheetRoute<T> route;
  216 + final bool isScrollControlled;
  217 + final Color backgroundColor;
  218 + final double elevation;
  219 + final ShapeBorder shape;
  220 + final Clip clipBehavior;
  221 + final bool enableDrag;
  222 +
  223 + @override
  224 + // ignore: lines_longer_than_80_chars
  225 + _GetPerModalBottomSheetState<T> createState() =>
  226 + _GetPerModalBottomSheetState<T>();
  227 +}
  228 +
  229 +// ignore: lines_longer_than_80_chars
  230 +class _GetPerModalBottomSheetState<T>
  231 + extends State<_GetPerModalBottomSheet<T>> {
  232 + String _getRouteLabel(MaterialLocalizations localizations) {
  233 + if ((Theme.of(context).platform == TargetPlatform.android) ||
  234 + (Theme.of(context).platform == TargetPlatform.fuchsia)) {
  235 + return localizations.dialogLabel;
  236 + } else {
  237 + return '';
  238 + }
  239 + }
  240 +
  241 + @override
  242 + Widget build(BuildContext context) {
  243 + assert(debugCheckHasMediaQuery(context));
  244 + assert(debugCheckHasMaterialLocalizations(context));
  245 + final mediaQuery = MediaQuery.of(context);
  246 + final localizations = MaterialLocalizations.of(context);
  247 + final routeLabel = _getRouteLabel(localizations);
  248 +
  249 + return AnimatedBuilder(
  250 + animation: widget.route.animation,
  251 + builder: (context, child) {
  252 + // Disable the initial animation when accessible navigation is on so
  253 + // that the semantics are added to the tree at the correct time.
  254 + final animationValue = mediaQuery.accessibleNavigation
  255 + ? 1.0
  256 + : widget.route.animation.value;
  257 + return Semantics(
  258 + scopesRoute: true,
  259 + namesRoute: true,
  260 + label: routeLabel,
  261 + explicitChildNodes: true,
  262 + child: ClipRect(
  263 + child: CustomSingleChildLayout(
  264 + delegate: _GetModalBottomSheetLayout(
  265 + animationValue, widget.isScrollControlled),
  266 + child: widget.isPersistent == false
  267 + ? BottomSheet(
  268 + animationController: widget.route._animationController,
  269 + onClosing: () {
  270 + if (widget.route.isCurrent) {
  271 + Navigator.pop(context);
  272 + }
  273 + },
  274 + builder: widget.route.builder,
  275 + backgroundColor: widget.backgroundColor,
  276 + elevation: widget.elevation,
  277 + shape: widget.shape,
  278 + clipBehavior: widget.clipBehavior,
  279 + enableDrag: widget.enableDrag,
  280 + )
  281 + : Scaffold(
  282 + bottomSheet: BottomSheet(
  283 + animationController:
  284 + widget.route._animationController,
  285 + onClosing: () {
  286 + // if (widget.route.isCurrent) {
  287 + // Navigator.pop(context);
  288 + // }
  289 + },
  290 + builder: widget.route.builder,
  291 + backgroundColor: widget.backgroundColor,
  292 + elevation: widget.elevation,
  293 + shape: widget.shape,
  294 + clipBehavior: widget.clipBehavior,
  295 + enableDrag: widget.enableDrag,
  296 + ),
  297 + )),
  298 + ),
  299 + );
  300 + },
  301 + );
  302 + }
  303 +}
  304 +
  305 +class _GetModalBottomSheetLayout extends SingleChildLayoutDelegate {
  306 + _GetModalBottomSheetLayout(this.progress, this.isScrollControlled);
  307 +
  308 + final double progress;
  309 + final bool isScrollControlled;
  310 +
  311 + @override
  312 + BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
  313 + return BoxConstraints(
  314 + minWidth: constraints.maxWidth,
  315 + maxWidth: constraints.maxWidth,
  316 + minHeight: 0.0,
  317 + maxHeight: isScrollControlled
  318 + ? constraints.maxHeight
  319 + : constraints.maxHeight * 9.0 / 16.0,
  320 + );
  321 + }
  322 +
  323 + @override
  324 + Offset getPositionForChild(Size size, Size childSize) {
  325 + return Offset(0.0, size.height - childSize.height * progress);
  326 + }
  327 +
  328 + @override
  329 + bool shouldRelayout(_GetModalBottomSheetLayout oldDelegate) {
  330 + return progress != oldDelegate.progress;
  331 + }
  332 +}
  1 +import 'package:flutter/widgets.dart';
  2 +import '../../../get_core/get_core.dart';
  3 +import '../../../get_instance/src/get_instance.dart';
  4 +
  5 +class GetDialogRoute<T> extends PopupRoute<T> {
  6 + GetDialogRoute({
  7 + @required RoutePageBuilder pageBuilder,
  8 + bool barrierDismissible = true,
  9 + String barrierLabel,
  10 + Color barrierColor = const Color(0x80000000),
  11 + Duration transitionDuration = const Duration(milliseconds: 200),
  12 + RouteTransitionsBuilder transitionBuilder,
  13 + RouteSettings settings,
  14 + }) : assert(barrierDismissible != null),
  15 + widget = pageBuilder,
  16 + name = "DIALOG: ${pageBuilder.hashCode}",
  17 + _barrierDismissible = barrierDismissible,
  18 + _barrierLabel = barrierLabel,
  19 + _barrierColor = barrierColor,
  20 + _transitionDuration = transitionDuration,
  21 + _transitionBuilder = transitionBuilder,
  22 + super(settings: settings);
  23 +
  24 + final RoutePageBuilder widget;
  25 +
  26 + @override
  27 + bool get barrierDismissible => _barrierDismissible;
  28 + final bool _barrierDismissible;
  29 +
  30 + final String name;
  31 +
  32 + @override
  33 + void dispose() {
  34 + if (Get.smartManagement != SmartManagement.onlyBuilder) {
  35 + WidgetsBinding.instance.addPostFrameCallback(
  36 + (_) => GetInstance().removeDependencyByRoute(name));
  37 + }
  38 + super.dispose();
  39 + }
  40 +
  41 + @override
  42 + String get barrierLabel => _barrierLabel;
  43 + final String _barrierLabel;
  44 +
  45 + @override
  46 + Color get barrierColor => _barrierColor;
  47 + final Color _barrierColor;
  48 +
  49 + @override
  50 + Duration get transitionDuration => _transitionDuration;
  51 + final Duration _transitionDuration;
  52 +
  53 + final RouteTransitionsBuilder _transitionBuilder;
  54 +
  55 + @override
  56 + Widget buildPage(BuildContext context, Animation<double> animation,
  57 + Animation<double> secondaryAnimation) {
  58 + return Semantics(
  59 + child: widget(context, animation, secondaryAnimation),
  60 + scopesRoute: true,
  61 + explicitChildNodes: true,
  62 + );
  63 + }
  64 +
  65 + @override
  66 + Widget buildTransitions(BuildContext context, Animation<double> animation,
  67 + Animation<double> secondaryAnimation, Widget child) {
  68 + if (_transitionBuilder == null) {
  69 + return FadeTransition(
  70 + opacity: CurvedAnimation(
  71 + parent: animation,
  72 + curve: Curves.linear,
  73 + ),
  74 + child: child);
  75 + } // Some default transition
  76 + return _transitionBuilder(context, animation, secondaryAnimation, child);
  77 + }
  78 +}