Primeros pasos con el paquete GetX en aplicaciones Flutter
Publicado: 2022-03-10Flutter es una de las formas más rápidas de crear aplicaciones nativas verdaderamente multiplataforma. Proporciona funciones que permiten al desarrollador crear una experiencia de interfaz de usuario verdaderamente hermosa para sus usuarios.
Sin embargo, la mayoría de las veces para lograr cosas como navegar a las pantallas, administrar el estado y mostrar alertas, se necesitan muchos repeticiones. Estos modelos tienden a ralentizar la eficiencia de desarrollo de los desarrolladores que intentan crear funciones y cumplir con los plazos.
Tomemos, por ejemplo, el modelo necesario para navegar a una pantalla en una aplicación de Flutter. Supongamos que desea navegar a una pantalla llamada AboutScreen
. tendrás que escribir:
Navigator.push( context, MaterialPageRoute(builder: (context) => AboutScreen()), );
Sería más eficiente y amigable para los desarrolladores hacer algo como:
Get.to(AboutScreen());
Cuando necesite navegar de regreso a la página anterior en Flutter, deberá escribir:
Navigator.pop(context);
Notará que siempre dependemos de la propiedad de contexto para algo tan común como navegar entre pantallas. ¿Qué pasa si en cambio, podemos hacer algo como esto:
Get.back();
Los ejemplos anteriores son algunas de las formas en que se puede mejorar el desarrollo de aplicaciones en Flutter para que sea más intuitivo y eficiente con menos repeticiones. Si prefiere la simplicidad y la eficiencia en la creación de funciones e ideas, en Flutter, el paquete Get le interesará.
¿Qué es GetX?
Get o GetX es un marco rápido, estable y extraligero para crear aplicaciones Flutter.
GetX viene listo para usar con administración de estado de alto rendimiento, inyección de dependencia inteligente y administración de rutas de una manera simple y práctica.
GetX tiene como objetivo minimizar las repeticiones al mismo tiempo que proporciona una sintaxis simple e intuitiva para que los desarrolladores la utilicen mientras crean sus aplicaciones. En el núcleo de GetX se encuentran estos 3 principios:
- Rendimiento
GetX se enfoca en el desempeño de su aplicación al implementar sus funciones para consumir la menor cantidad de recursos posible. - Productividad
GetX quiere que los desarrolladores utilicen sus funciones para ser productivos lo más rápido posible. Lo hace empleando una sintaxis y prácticas fáciles de recordar. Por ejemplo, en general, el desarrollador debe preocuparse por eliminar los controladores de la memoria, pero GetX listo para usar proporciona una administración inteligente que supervisa los controladores en su aplicación y los elimina cuando no se usan de manera predeterminada. - Organización
GetX permite el desacoplamiento de la vista, la lógica de presentación, la lógica comercial, la inyección de dependencia y la navegación en su aplicación Flutter. No necesita contexto para navegar entre rutas, por lo que no depende del árbol de widgets para la navegación. No necesita contexto para acceder a sus controladores/bloques a través de uninheritedWidget
, por lo que puede desacoplar completamente su lógica de presentación y lógica de negocios de su capa de vista. No necesita inyectar sus clases de Controladores/Modelos/Bloques en su árbol de widgets a través de múltiples proveedores, para esto GetX usa su propia característica de inyección de dependencia, desacoplando el DI de su vista por completo.
Características de GetX
GetX viene con un par de funciones que necesitará en su desarrollo diario de aplicaciones en Flutter. Veámoslos:
Administración del Estado
Una de las características principales de GetX es su función intuitiva de administración de estado. La administración de estado en GetX se puede lograr con poco o ningún texto estándar.
Gestión de rutas
GetX proporciona API para navegar dentro de la aplicación Flutter. Esta API es simple y requiere menos código.
Gestión de dependencias
GetX proporciona una forma inteligente de administrar las dependencias en su aplicación Flutter, como los controladores de vista. GetX eliminará de la memoria cualquier controlador que no se esté utilizando en ese momento. Esta fue una tarea que usted, como desarrollador, tendrá que hacer manualmente, pero GetX lo hace automáticamente de forma inmediata.
internacionalización
GetX proporciona i18n listo para usar, lo que le permite escribir aplicaciones con compatibilidad con varios idiomas.
Validación
GetX proporciona métodos de validación para realizar la validación de entrada en sus aplicaciones Flutter. Esto es bastante conveniente ya que no necesitaría instalar un paquete de validación por separado.
Almacenamiento
GetX proporciona un valor clave rápido, extra ligero y síncrono en la memoria, que realiza una copia de seguridad de los datos en el disco en cada operación. Está escrito completamente en Dart y se integra fácilmente con el paquete principal de GetX.
Primeros pasos con GetX
Ahora que ha visto qué es GetX y las características y beneficios que brinda, veamos cómo configurarlo en su aplicación. Construiremos una aplicación de demostración para ver la mayoría de las funciones que hemos mencionado en acción. Empecemos.
Crear una nueva aplicación Flutter
Comenzaremos creando una nueva aplicación de Flutter a través de la CLI de Flutter. Supongo que su máquina ya está configurada para el desarrollo de aplicaciones con Flutter. Así que ejecutamos:
flutter create getx_demo
Esto generará el código básico necesario para una aplicación Flutter. A continuación, abra el proyecto que acaba de crear en el editor de su elección (Usaremos VS Code para este artículo). Luego ejecutaremos el proyecto para asegurarnos de que funciona bien (asegúrese de tener un dispositivo conectado o un emulador/simulador en ejecución).
Cuando se ejecuta la aplicación, verá la aplicación de contador predeterminada que Flutter crea para usted cuando crea una nueva aplicación de Flutter. Lo que vamos a hacer es implementar la misma aplicación de contador pero con GetX para administrar el estado de la aplicación (que es la variable de conteo).
Comenzaremos limpiando main.dart
y dejando solo este fragmento de código:
# main.dart import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
A estas alturas, nuestra aplicación se habría roto ya que ya no existe el widget MyHomePage
. Arreglemos eso. Con GetX, no necesitamos widgets con estado y también nuestra interfaz de usuario se puede separar claramente de nuestra lógica comercial. Así que crearemos dos directorios dentro lib/
. Estos directorios son:
views/ | Para sostener las pantallas en nuestra aplicación. |
controllers/ | Para mantener todos los controladores de las pantallas en nuestra aplicación. |
Vamos a crear el widget MyHomePage
dentro de views/
. El nombre del archivo será my_home_page.dart
. Después de crearlo, agréguele el siguiente fragmento de código:
import 'package:flutter/material.dart'; class MyHomePage extends StatelessWidget { final String title; MyHomePage({this.title}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( '0', style: Theme.of(context).textTheme.headline4, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: null, tooltip: 'Increment', child: Icon(Icons.add), ), ); } }
Ahora que tenemos el widget MyHomePage
, importémoslo en main.dart
. Agregue la declaración de importación en la parte superior de main.dart debajo import 'package:flutter/material.dart';
import './views/my_home_page.dart';
Ahora su archivo main.dart
debería verse así:
import 'package:flutter/material.dart'; import './views/my_home_page.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
Cuando guarde su aplicación ahora, todos los errores deberían haberse solucionado y la aplicación se ejecutará. Pero notará que cuando vuelva a hacer clic en el botón, el contador no se actualizará. Si observa el código views/my_home_page.dart
, verá que simplemente estamos codificando 0
como el valor del widget de texto y pasando null
al controlador onPressed
del botón. Incorporemos GetX a la mezcla para que la aplicación vuelva a funcionar.
Instalando GetX
Diríjase a la página de instalación de GetX en pub.dev y verá la línea de código para copiar en su archivo pubspec.yml
para instalar GetX. Al momento de escribir este artículo, la versión actual de GetX es 3.23.1. Así que copiaremos la línea:
get: ^3.23.1
Y luego péguelo en la sección de dependencies
de nuestro archivo pubspec.yml
. Cuando guarde el archivo, get debería instalarse automáticamente. O puede ejecutar manualmente en su terminal.
flutter pub get
La sección de dependencias de su archivo pubspec.yml
debería verse así:
dependencies: flutter: sdk: flutter get: ^3.23.1
GetxController
Hemos mencionado que GetX le permite separar la interfaz de usuario de su aplicación de la lógica. Lo hace proporcionando una clase GetxController
que puede heredar para crear clases de controlador para las vistas de su aplicación. Para nuestra aplicación actual, tenemos una vista, por lo que crearemos un controlador para esa vista. Dirígete al directorio controllers/
y crea un archivo llamado my_home_page_controller.dart
. Esto mantendrá el controlador para la vista MyHomePage
.
Una vez que haya creado el archivo, primero importe el paquete GetX agregando esto en la parte superior del archivo:
import 'package:get/get.dart';
Luego, creará una clase llamada MyHomePageController
dentro de ella y extenderá la clase GetxController
. Así es como debería verse el archivo:
import 'package:get/get.dart'; class MyHomePageController extends GetxController {}
agreguemos el estado de conteo a la clase que hemos creado.
final count = 0;
En GetX, para hacer que una variable sea observable, esto significa que cuando cambie, se notificará a otras partes de nuestra aplicación que dependan de ella. Para hacer esto, simplemente necesitamos agregar .obs
a la inicialización de la variable. Entonces, para nuestra variable de count
anterior, agregaremos .obs
a 0
. Entonces, la declaración anterior ahora se verá así:
final count = 0.obs;
Así es como se ve nuestro archivo de controlador en este momento:
import 'package:get/get.dart'; class MyHomePageController extends GetxController { final count = 0.obs; }
Para concluir con MyHomePageController
, implementaremos el método de increment
. Este es el fragmento para hacer eso:
increment() => count.value++;
Notará que necesitábamos agregar .value
a la variable de conteo para incrementarla. Hicimos esto porque agregar .obs
a una variable la convierte en una variable observable y para obtener el valor de una variable observable, lo hace desde la propiedad de value
.
Así que hemos terminado con el controlador. Ahora, cuando el valor de conteo cambie, cualquier parte de nuestra aplicación que lo use se actualizará automáticamente.
Ahora nos dirigiremos a nuestra vista y le informaremos sobre el controlador que acabamos de crear. Lo haremos instanciando la clase de controlador utilizando la función de gestión de dependencias de GetX. Esto asegurará que nuestro controlador no estará en la memoria cuando ya no sea necesario.
En views/my_home_page.dart
importa el paquete Get y también el controlador que creaste así:
import 'package:get/get.dart'; import '../controllers/my_home_page_controller.dart';
Luego, dentro de la clase MyHomePage
una instancia de MyHomePageController
:
final MyHomePageController controller = Get.put(MyHomePageController());
Ahora que tenemos una instancia de MyHomePageController
, podemos usar la variable de estado y el método. Entonces, comenzando con el estado, en GetX para marcar una parte de su interfaz de usuario para que se reconstruya cuando cambie una variable de estado, envolverá esa parte con el widget Obx
. GetX proporciona otras formas de hacer esto, pero este método es mucho más simple y limpio.
Para nuestra aplicación de conteo, queremos que el widget de texto se actualice con el conteo actual. Así que envolveremos el widget de Texto con el widget Obx
así:
Obx(() => Text('0',style: Theme.of(context).textTheme.headline4,),)
A continuación, reemplazaremos la cadena estática 0
con la variable de conteo de MyHomePageController
así:
Obx(() => Text('${controller.count.value}', ,style: Theme.of(context).textTheme.headline4,),)
Por último, llamaremos al método de incremento cuando se presione el botón de acción floatingActionButton
esta manera:
floatingActionButton: FloatingActionButton( onPressed: controller.increment, tooltip: 'Increment', child: Icon(Icons.add), ),
Entonces, en general, nuestro archivo de vista MyHomePage
ahora debería verse así:
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/my_home_page_controller.dart'; class MyHomePage extends StatelessWidget { final String title; final MyHomePageController controller = Get.put(MyHomePageController()); MyHomePage({this.title}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Obx( () => Text( '${controller.count.value}', style: Theme.of(context).textTheme.headline4, ), ) ], ), ), floatingActionButton: FloatingActionButton( onPressed: controller.increment, tooltip: 'Increment', child: Icon(Icons.add), ), ); } }
Cuando guarde su aplicación o la vuelva a ejecutar, la aplicación de contador debería funcionar como lo hizo cuando creamos la aplicación por primera vez.
Creo que ha visto lo intuitiva que es la administración de estado con GetX, no tuvimos que escribir muchos repetitivos y esta simplicidad será más obvia a medida que su aplicación se vuelva compleja. También notará que nuestra vista no contiene ni mantiene ningún estado, por lo que puede ser un widget sin estado. El cerebro de la vista, a su vez, ahora es una clase de controlador que mantendrá el estado de la vista y los métodos.
Navegación en GetX
Hemos visto la gestión del estado en GetX. Veamos ahora cómo GetX admite la navegación dentro de su aplicación. Para activar la función de navegación de GetX, solo necesita realizar un cambio en main.dart
que consiste en convertir el widget de MaterialApp
en un widget de GetMaterialApp
. Hagámoslo importando primero Obtener en la parte superior de main.dart
import 'package:get/get.dart';
Luego hacemos el cambio a MaterialApp
para que nuestro archivo main.dart
ahora se vea así:
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import './views/my_home_page.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return GetMaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
Ahora nuestra aplicación se ha configurado para admitir la navegación GetX. Para probar esto, crearemos otra vista en el directorio views/
. Llamaremos a esto en about_page.dart
y contendrá el siguiente código:
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/my_home_page_controller.dart'; class AboutPage extends StatelessWidget { final MyHomePageController controller = Get.put(MyHomePageController()); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('About GetX'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Padding( padding: const EdgeInsets.all(16.0), child: Text( '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.', ), ), ], ), ), ); } }
Luego iremos a MyHomePage
y agregaremos un botón que, cuando se presione, nos llevará a AboutPage
. Al igual que. El botón debe estar debajo del widget Obx. Aquí lo tienes:
FlatButton(onPressed: () {}, child: Text('About GetX'))
También necesitaremos importar AboutPage
en la parte superior del archivo MyHomePage
:
import './about_page.dart';
Para decirle a GetX que navegue a AboutPage
todo lo que necesitamos es una línea de código que es:
Get.to(AboutPage());
Agreguemos eso a la devolución de llamada onPressed
del widget FlatButton
así:
FlatButton( onPressed: () { Get.to(AboutPage()); }, child: Text('About GetX'))
Cuando guarde su solicitud ahora, podrá navegar hasta la AboutPage
de.
También puede optar por reemplazar la vista MyHomePage
con AboutPage
para que el usuario no pueda volver a la página anterior presionando el botón Atrás del dispositivo. Esto es útil para pantallas como las pantallas de inicio de sesión. Para hacer esto, reemplace el contenido del controlador onPressed
con el siguiente código:
Get.off(AboutPage());
Esto abrirá la vista MyHomePage
y la reemplazará con AboutPage
.
Ahora que podemos navegar a AboutPage
, creo que no será tan malo poder volver a MyHomePage
para hacer esto, agregaremos un botón en AboutPage
después del widget Padding y en su controlador onPressed
haremos una llamada a Get.back()
para volver a MyHomePage
:
FlatButton( onPressed: () { Get.back(); }, child: Text('Go Home') )
snack bar
En Flutter convencionalmente para mostrar un Snackbar, deberás escribir algo como esto:
final snackBar = SnackBar(content: Text('Yay! A SnackBar!')); // Find the Scaffold in the widget tree and use it to show a SnackBar. Scaffold.of(context).showSnackBar(snackBar);
Puede observar que todavía dependemos de la propiedad de context
. Veamos cómo podemos lograr esto en GetX. Vaya a la vista MyHomePage
y agregue otro widget FlatButton
debajo del último botón que agregamos. Aquí está el fragmento para el botón:
FlatButton( onPressed: () { // TODO: Implement Snackbar }, child: Text('Show Snackbar'))
Mostremos el mensaje '¡Yay! Impresionante barra de refrigerios GetX'. Dentro de la función del controlador onPressed, agregue la siguiente línea de código:
Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar');
Ejecute su aplicación y cuando haga clic en el botón "Mostrar barra de bocadillos", ¡verá una barra de bocadillos en la parte superior de su aplicación!
¿Ves cómo redujimos la cantidad de líneas necesarias para mostrar una barra de refrigerios en una aplicación de Flutter? Hagamos un poco más de personalización en el Snackbar; Hagamos que aparezca en la parte inferior de la aplicación. Cambia el código a esto:
Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar',snackPosition:SnackPosition.BOTTOM, );
Guarde y ejecute su aplicación y el Snackbar ahora aparecerá en la parte inferior de la aplicación. Que tal si cambiamos el color de fondo de la Snackbar ya que de momento es transparente. Lo cambiaremos a un color amberAccent
de la clase Colors
en Flutter. Actualice el código a esto:
Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar',snackPosition:SnackPosition.BOTTOM, backgroundColor: Colors.amberAccent );
En general, el código del botón debería verse así:
FlatButton( onPressed: () { Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.amberAccent); }, child: Text('Show Snackbar'))
Diálogo
GetX proporciona un método simple para crear AlertDialog en Flutter. Veámoslo en acción. Crea otro botón debajo del anterior:
FlatButton( onPressed: () { // TODO: Show alert dialog }, child: Text('Show AlertDialog'))
Llamemos a GetX para mostrar un diálogo de alerta:
Get.defaultDialog();
Eso mostrará un cuadro de diálogo de alerta predeterminado que se puede descartar tocando fuera del cuadro de diálogo. Puede ver cómo en una línea de código tenemos un cuadro de diálogo de alerta de trabajo. Vamos a personalizarlo un poco. Cambiemos el título y el mensaje:
Get.defaultDialog( title: 'GetX Alert', middleText: 'Simple GetX alert');
Guarde y ejecute su aplicación y verá los cambios cuando presione el botón "Mostrar diálogo de alerta". Podemos agregar botones de confirmación y cancelación así:
Get.defaultDialog( title: 'GetX Alert', middleText: 'Simple GetX alert', textConfirm: 'Okay', confirmTextColor: Colors.amberAccent, textCancel: 'Cancel');
Hay muchas formas de personalizar el cuadro de diálogo GetX y la API es bastante intuitiva y simple.
Conclusión
GetX se creó para mejorar la productividad de los desarrolladores de Flutter a medida que crean funciones. En lugar de tener que buscar la plantilla necesaria para hacer cosas como la administración del estado, la administración de la navegación y más, GetX proporciona una API sencilla e intuitiva para lograr estas actividades sin sacrificar el rendimiento. Este artículo le presenta GetX y cómo comenzar a usarlo en sus aplicaciones Flutter.
- Puede encontrar la demostración aquí →