Introdução ao pacote GetX em aplicativos Flutter
Publicados: 2022-03-10O Flutter é uma das maneiras mais rápidas de criar aplicativos nativos verdadeiramente multiplataforma. Ele fornece recursos que permitem ao desenvolvedor criar uma experiência de interface do usuário verdadeiramente bonita para seus usuários.
No entanto, na maioria das vezes, para alcançar coisas como navegar para telas, gerenciamento de estado e mostrar alertas, são necessários muitos clichês. Esses clichês tendem a diminuir a eficiência de desenvolvimento dos desenvolvedores que tentam construir recursos e cumprir seus prazos.
Tomemos, por exemplo, o clichê necessário para navegar para uma tela em um aplicativo Flutter. Digamos que você queira navegar para uma tela chamada AboutScreen
. você terá que escrever:
Navigator.push( context, MaterialPageRoute(builder: (context) => AboutScreen()), );
Seria mais eficiente e amigável ao desenvolvedor fazer algo como:
Get.to(AboutScreen());
Quando você precisar navegar de volta para a página anterior no Flutter, você terá que escrever:
Navigator.pop(context);
Você notará que estamos sempre dependendo da propriedade context para algo tão comum quanto navegar entre as telas. E se, em vez disso, pudéssemos fazer algo assim:
Get.back();
Os exemplos acima são algumas das maneiras pelas quais o desenvolvimento de aplicativos no Flutter pode ser aprimorado para ser mais intuitivo e eficiente com menos clichê. Se você favorece a simplicidade e a eficiência na criação de recursos e ideias, no Flutter, o pacote Get lhe interessará.
O que é GetX
Get ou GetX é uma estrutura rápida, estável e extra-leve para a construção de aplicativos Flutter.
O GetX vem pronto para uso com gerenciamento de estado de alto desempenho, injeção de dependência inteligente e gerenciamento de rotas de maneira simplista e prática.
O GetX visa minimizar os clichês e, ao mesmo tempo, fornecer uma sintaxe simples e intuitiva para os desenvolvedores usarem durante a construção de seus aplicativos. No núcleo do GetX estão estes 3 princípios:
- atuação
O GetX foca no desempenho do seu aplicativo implementando seus recursos para consumir o mínimo de recursos possível. - Produtividade
A GetX quer que os desenvolvedores usem seus recursos para serem produtivos o mais rápido possível. Ele faz isso empregando sintaxe e práticas fáceis de lembrar. Por exemplo, geralmente, o desenvolvedor deve se preocupar em remover os controladores da memória, mas o GetX pronto para uso fornece gerenciamento inteligente que monitora os controladores em seu aplicativo e os remove quando não estão sendo usados por padrão. - Organização
GetX permite o desacoplamento da View, lógica de apresentação, lógica de negócios, injeção de dependência e navegação em seu aplicativo Flutter. Você não precisa de contexto para navegar entre as rotas, portanto, não depende da árvore de widgets para navegação. Você não precisa de contexto para acessar seus controladores/blocos por meio deinheritedWidget
, portanto, pode desacoplar completamente sua lógica de apresentação e lógica de negócios da 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 este GetX usa seu próprio recurso de injeção de dependência, desacoplando completamente a DI de sua visão.
Recursos do GetX
O GetX vem com alguns recursos que você precisará no desenvolvimento diário de aplicativos no Flutter. Vamos olhar para eles:
Gerenciamento de estado
Um dos principais recursos do GetX é seu recurso intuitivo de gerenciamento de estado. O gerenciamento de estado no GetX pode ser obtido com pouco ou nenhum clichê.
Gerenciamento de rotas
GetX fornece API para navegar dentro do aplicativo Flutter. Esta API é simples e com menos código necessário.
Gerenciamento de Dependências
GetX fornece uma maneira inteligente de gerenciar dependências em seu aplicativo Flutter, como os controladores de exibição. GetX removerá qualquer controlador que não esteja sendo usado no momento da memória. Esta foi uma tarefa que você, como desenvolvedor, terá que fazer manualmente, mas o GetX faz isso automaticamente para você.
Internacionalização
GetX fornece i18n pronto para uso, permitindo que você escreva aplicativos com suporte a vários idiomas.
Validação
GetX fornece métodos de validação para realizar validação de entrada em seus aplicativos Flutter. Isso é bastante conveniente, pois você não precisaria instalar um pacote de validação separado.
Armazenar
GetX fornece um valor-chave rápido, leve e síncrono na memória, que faz backup de dados em disco em cada operação. Ele é escrito inteiramente em Dart e se integra facilmente com o pacote principal do GetX.
Introdução ao GetX
Agora que você viu o que é GetX e os recursos e benefícios que ele oferece, vamos ver como configurá-lo em seu aplicativo. Construiremos um aplicativo de demonstração para ver a maioria dos recursos que mencionamos em ação. Vamos começar.
Crie um novo aplicativo Flutter
Começaremos criando um novo aplicativo Flutter por meio da CLI do Flutter. Estou assumindo que sua máquina já está configurada para desenvolvimento de aplicativos com o Flutter. Então corremos:
flutter create getx_demo
Isso gerará o código básico necessário para um aplicativo Flutter. Em seguida, abra o projeto que você acabou de criar no editor de sua escolha (vamos usar o VS Code para este artigo). Em seguida, executaremos o projeto para ter certeza de que está funcionando bem (certifique-se de ter um dispositivo conectado ou um emulador/simulador em execução).
Quando o aplicativo for executado, você verá o aplicativo de contador padrão que o Flutter scaffold para você ao criar um novo aplicativo Flutter. O que vamos fazer é implementar o mesmo aplicativo contador, mas com GetX para gerenciar o estado do aplicativo (que é a variável de contagem).
Começaremos limpando main.dart
e deixando apenas este trecho 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'), ); } }
Até agora, nosso aplicativo estaria quebrado, pois não há mais o widget MyHomePage
. Vamos consertar isso. Com GetX, não precisamos de widgets com estado e também nossa interface do usuário pode ser claramente separada de nossa lógica de negócios. Então vamos criar dois diretórios dentro lib/
. Esses diretórios são:
views/ | Para segurar as telas em nosso aplicativo. |
controllers/ | Para manter todos os controladores para as telas em nosso aplicativo. |
Vamos criar o widget MyHomePage
dentro de views/
. O nome do arquivo será my_home_page.dart
. Depois de criá-lo, adicione o seguinte trecho de código a ele:
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), ), ); } }
Agora temos o widget MyHomePage
, vamos importá-lo em main.dart
. Adicione a instrução de importação no topo de main.dart abaixo de import 'package:flutter/material.dart';
import './views/my_home_page.dart';
Agora seu arquivo main.dart
deve ficar assim:
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'), ); } }
Quando você salva seu aplicativo agora, todos os erros devem ter sido corrigidos e o aplicativo será executado. Mas você notará quando clicar no botão novamente, o contador não será atualizado. Se você observar o código views/my_home_page.dart
, verá que estamos apenas codificando 0
como o valor do widget Text e passando null
para o manipulador onPressed
do botão. Vamos trazer o GetX para a mistura para tornar o aplicativo funcional novamente.
Instalando o GetX
Vá até a página de instalação do GetX em pub.dev e você verá a linha de código a ser copiada para colocar em seu arquivo pubspec.yml
para instalar o GetX. No momento da redação deste artigo, a versão atual do GetX é 3.23.1. Então vamos copiar a linha:
get: ^3.23.1
E cole-o na seção de dependencies
do nosso arquivo pubspec.yml
. Quando você salva o arquivo, get deve ser instalado automaticamente para você. Ou você pode executar manualmente no seu terminal.
flutter pub get
A seção de dependências do seu arquivo pubspec.yml
deve ficar assim:
dependencies: flutter: sdk: flutter get: ^3.23.1
GetxController
Mencionamos que o GetX permite que você separe a interface do usuário do seu aplicativo da lógica. Ele faz isso fornecendo uma classe GetxController
que você pode herdar para criar classes de controlador para as visualizações do seu aplicativo. Para nosso aplicativo atual, temos uma visualização, portanto, criaremos um controlador para essa visualização. Vá até o diretório controllers/
e crie um arquivo chamado my_home_page_controller.dart
. Isso manterá o controlador para a exibição MyHomePage
.
Depois de criar o arquivo, primeiro importe o pacote GetX adicionando-o ao topo do arquivo:
import 'package:get/get.dart';
Em seguida, você criará uma classe chamada MyHomePageController
dentro dela e estenderá a classe GetxController
. É assim que o arquivo deve ficar:
import 'package:get/get.dart'; class MyHomePageController extends GetxController {}
vamos adicionar o estado de contagem à classe que criamos.
final count = 0;
No GetX, para tornar uma variável observável — isso significa que, quando ela for alterada, outras partes do nosso aplicativo, dependendo dela, serão notificadas. Para fazer isso, basta adicionar .obs
à inicialização da variável. Portanto, para nossa variável de count
acima, adicionaremos .obs
a 0
. Portanto, a declaração acima agora ficará assim:
final count = 0.obs;
É assim que nosso arquivo de controlador se parece no momento:
import 'package:get/get.dart'; class MyHomePageController extends GetxController { final count = 0.obs; }
Para encerrar as coisas com o MyHomePageController
, implementaremos o método de increment
. Este é o trecho para fazer isso:
increment() => count.value++;
Você notará que precisamos adicionar .value
à variável count para incrementá-la. Fizemos isso porque adicionar .obs
a uma variável a torna uma variável observável e para obter o valor de uma variável observável, você faz isso a partir da propriedade value
.
Então, terminamos com o controlador. Agora, quando o valor de count mudar, qualquer parte do nosso aplicativo que o use será atualizado automaticamente.
Agora iremos para nossa view e informaremos sobre o controller que acabamos de criar. Faremos isso instanciando a classe do controlador usando o recurso de gerenciamento de dependência GetX. Isso garantirá que nosso controlador não estará na memória quando não for mais necessário.
Em views/my_home_page.dart
importe o pacote Get e também o controller que você criou assim:
import 'package:get/get.dart'; import '../controllers/my_home_page_controller.dart';
Então dentro da classe MyHomePage
vamos instanciar o MyHomePageController
:
final MyHomePageController controller = Get.put(MyHomePageController());
Agora temos uma instância do MyHomePageController
, podemos usar a variável de estado assim como o método. Então, começando com o estado, no GetX para marcar uma parte de sua interface do usuário para ser reconstruída quando uma variável de estado for alterada, você envolverá essa parte com o widget Obx
. GetX fornece outras maneiras de fazer isso, mas esse método é muito mais simples e limpo.
Para nosso aplicativo de contagem, queremos que o widget de texto seja atualizado com a contagem atual. Então, vamos envolver o widget Text com o widget Obx
da seguinte forma:
Obx(() => Text('0',style: Theme.of(context).textTheme.headline4,),)
Em seguida, substituiremos a string estática 0
pela variável de contagem do MyHomePageController
assim:
Obx(() => Text('${controller.count.value}', ,style: Theme.of(context).textTheme.headline4,),)
Por fim, chamaremos o método increment quando o floatingActionButton
for pressionado assim:
floatingActionButton: FloatingActionButton( onPressed: controller.increment, tooltip: 'Increment', child: Icon(Icons.add), ),
Portanto, no geral, nosso arquivo de visualização MyHomePage
agora deve ficar assim:
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), ), ); } }
Quando você salva seu aplicativo ou o executa novamente, o aplicativo do contador deve funcionar como quando criamos o aplicativo.
Acredito que você tenha visto como o gerenciamento de estado é intuitivo com o GetX, não tivemos que escrever muito clichê e essa simplicidade será mais óbvia à medida que sua aplicação se tornar complexa. Você também notará que nossa visão não mantém ou mantém nenhum estado, portanto, pode ser um widget sem estado. O cérebro da visão, por sua vez, é agora uma classe controladora que manterá o estado da visão e dos métodos.
Navegação no GetX
Vimos gerenciamento de estado no GetX. Vejamos agora como o GetX oferece suporte à navegação em seu aplicativo. Para ativar o recurso de navegação do GetX, você só precisa fazer uma alteração no main.dart
, que é transformar o widget MaterialApp
em um widget GetMaterialApp
. Vamos fazer isso primeiro importando Get no topo de main.dart
import 'package:get/get.dart';
Em seguida, fazemos a alteração no MaterialApp
para que nosso arquivo main.dart
assim:
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'), ); } }
Agora nosso aplicativo foi configurado para suportar a navegação GetX. Para testar isso, vamos criar outra view no diretório views/
. Chamaremos isso em about_page.dart
e conterá o seguinte 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.', ), ), ], ), ), ); } }
Em seguida, iremos para MyHomePage
e adicionaremos um botão que, quando pressionado, nos levará à AboutPage
. Igual a. O botão deve estar abaixo do widget Obx. Aqui está:
FlatButton(onPressed: () {}, child: Text('About GetX'))
Também precisaremos importar o AboutPage
no topo do arquivo MyHomePage
:
import './about_page.dart';
Para dizer ao GetX para navegar até a AboutPage
, tudo o que precisamos é de uma linha de código que é:
Get.to(AboutPage());
Vamos adicionar isso ao retorno de chamada onPressed
do widget FlatButton
assim:
FlatButton( onPressed: () { Get.to(AboutPage()); }, child: Text('About GetX'))
Ao salvar seu aplicativo agora, você poderá navegar até a AboutPage
.
Você também pode optar por substituir a exibição MyHomePage
pela AboutPage
para que o usuário não possa navegar de volta para a página anterior pressionando o botão Voltar do dispositivo. Isso é útil para telas como telas de login. Para fazer isso, substitua o conteúdo do manipulador onPressed
pelo código abaixo:
Get.off(AboutPage());
Isso abrirá a exibição MyHomePage
e a substituirá por AboutPage
.
Agora que podemos navegar para o AboutPage
, acho que não será tão ruim poder voltar ao MyHomePage
para fazer isso, adicionaremos um botão no AboutPage
após o widget Padding e no manipulador onPressed
faremos uma chamada para Get.back()
para navegar de volta para MyHomePage
:
FlatButton( onPressed: () { Get.back(); }, child: Text('Go Home') )
Lanchonete
No Flutter convencionalmente para mostrar um Snackbar, você precisará escrever algo assim:
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);
Você pode observar que ainda estamos dependendo da propriedade context
. Vamos ver como podemos conseguir isso no GetX. Vá para a visualização MyHomePage
e adicione outro widget FlatButton
abaixo do último botão que adicionamos. Segue o trecho do botão:
FlatButton( onPressed: () { // TODO: Implement Snackbar }, child: Text('Show Snackbar'))
Vamos exibir a mensagem 'Yay! Impressionante GetX Snackbar'. Dentro da função do manipulador onPressed, adicione a linha de código abaixo:
Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar');
Execute seu aplicativo e quando você clicar no botão “Mostrar Snackbar” você verá um snackbar em cima de seu aplicativo!
Viu como reduzimos o número de linhas necessárias para mostrar uma lanchonete em um aplicativo Flutter? Vamos fazer mais algumas customizações no Snackbar; Vamos fazê-lo aparecer na parte inferior do aplicativo. Altere o código para isso:
Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar',snackPosition:SnackPosition.BOTTOM, );
Salve e execute seu aplicativo e o Snackbar agora aparecerá na parte inferior do aplicativo. Que tal mudarmos a cor de fundo do Snackbar, pois no momento está transparente. Vamos alterá-lo para uma cor amberAccent
da classe Colors
no Flutter. Atualize o código para isso:
Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar',snackPosition:SnackPosition.BOTTOM, backgroundColor: Colors.amberAccent );
No geral, o código do botão deve ficar assim:
FlatButton( onPressed: () { Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.amberAccent); }, child: Text('Show Snackbar'))
Diálogo
GetX fornece um método simples para criar AlertDialog no Flutter. Vamos vê-lo em ação. Crie outro botão abaixo do anterior:
FlatButton( onPressed: () { // TODO: Show alert dialog }, child: Text('Show AlertDialog'))
Vamos chamar GetX para exibir uma caixa de diálogo de alerta:
Get.defaultDialog();
Isso mostrará uma caixa de diálogo de alerta padrão que pode ser dispensada tocando fora da caixa de diálogo. Você pode ver como em uma linha de código temos uma caixa de diálogo de alerta funcionando. Vamos personalizar um pouco. Vamos alterar o título e a mensagem:
Get.defaultDialog( title: 'GetX Alert', middleText: 'Simple GetX alert');
Salve e execute seu aplicativo e você verá as alterações quando clicar no botão “Show AlertDialog”. Podemos adicionar os botões confirmar e Cancelar assim:
Get.defaultDialog( title: 'GetX Alert', middleText: 'Simple GetX alert', textConfirm: 'Okay', confirmTextColor: Colors.amberAccent, textCancel: 'Cancel');
Existem muitas maneiras de personalizar a caixa de diálogo GetX e a API é bastante intuitiva e simples.
Conclusão
O GetX foi criado para melhorar a produtividade dos desenvolvedores Flutter à medida que eles desenvolvem recursos. Em vez de ter que procurar o clichê necessário para fazer coisas como gerenciamento de estado, gerenciamento de navegação e muito mais, o GetX fornece uma API simples e intuitiva para realizar essas atividades sem sacrificar o desempenho. Este artigo apresenta o GetX e como começar a usá-lo em seus aplicativos Flutter.
- Você pode encontrar a demonstração aqui →