Начало работы с пакетом GetX в приложениях Flutter
Опубликовано: 2022-03-10Flutter — один из самых быстрых способов создания действительно кроссплатформенных нативных приложений. Он предоставляет функции, позволяющие разработчику создавать действительно красивый пользовательский интерфейс для своих пользователей.
Однако в большинстве случаев для достижения таких вещей, как навигация по экранам, управление состоянием и отображение предупреждений, требуется множество шаблонов. Эти шаблоны, как правило, снижают эффективность разработки разработчиков, пытающихся создать функции и уложиться в сроки.
Возьмем, к примеру, шаблон, необходимый для перехода к экрану в приложении Flutter. Допустим, вы хотите перейти на экран под названием AboutScreen
. вам нужно будет написать:
Navigator.push( context, MaterialPageRoute(builder: (context) => AboutScreen()), );
Было бы более эффективно и удобно для разработчиков сделать что-то вроде:
Get.to(AboutScreen());
Когда вам нужно вернуться на предыдущую страницу во Flutter, вам нужно будет написать:
Navigator.pop(context);
Вы заметите, что мы всегда зависим от свойства контекста для чего-то такого банального, как навигация между экранами. Что, если вместо этого мы можем сделать что-то вроде этого:
Get.back();
Вышеприведенные примеры — это некоторые из способов улучшения разработки приложений во Flutter, чтобы сделать их более интуитивно понятными и эффективными с меньшим количеством шаблонов. Если вы предпочитаете простоту и эффективность в создании функций и идей, во Flutter вас заинтересует пакет Get.
Что такое GetX
Get или GetX — это быстрая, стабильная и сверхлегкая платформа для создания приложений Flutter.
GetX поставляется с готовым к использованию высокопроизводительным управлением состоянием, интеллектуальным внедрением зависимостей и простым и практичным управлением маршрутами.
GetX стремится свести к минимуму шаблоны, а также предоставить разработчикам простой и интуитивно понятный синтаксис для использования при создании своих приложений. В основе GetX лежат эти 3 принципа:
- Представление
GetX фокусируется на производительности вашего приложения, реализуя его функции, чтобы потреблять как можно меньше ресурсов. - Производительность
GetX хочет, чтобы разработчики использовали его функции, чтобы работать продуктивнее как можно быстрее. Это достигается за счет легкого для запоминания синтаксиса и практики. Например, как правило, разработчик должен позаботиться об удалении контроллеров из памяти, но GetX из коробки обеспечивает интеллектуальное управление, которое отслеживает контроллеры в вашем приложении и удаляет их, когда они не используются по умолчанию. - Организация
GetX позволяет разделить представление, логику представления, бизнес-логику, внедрение зависимостей и навигацию в вашем приложении Flutter. Вам не нужен контекст для навигации между маршрутами, поэтому вы не зависите от дерева виджетов для навигации. Вам не нужен контекст для доступа к вашим контроллерам/блокам черезinheritedWidget
, поэтому вы можете полностью отделить логику представления и бизнес-логику от уровня представления. Вам не нужно внедрять классы контроллеров/моделей/блоков в дерево виджетов через мультипровайдеров, поскольку GetX использует собственную функцию внедрения зависимостей, полностью отделяя DI от своего представления.
Особенности GetX
GetX поставляется с несколькими функциями, которые вам понадобятся при ежедневной разработке приложений во Flutter. Давайте посмотрим на них:
Государственное управление
Одной из флагманских функций GetX является интуитивно понятная функция управления состоянием. Управление состоянием в GetX может быть достигнуто практически без шаблонного кода.
Управление маршрутом
GetX предоставляет API для навигации в приложении Flutter. Этот API прост и требует меньше кода.
Управление зависимостями
GetX предоставляет умный способ управления зависимостями в вашем приложении Flutter, такими как контроллеры представления. GetX удалит из памяти любой неиспользуемый в данный момент контроллер. Это была задача, которую вам как разработчику придется выполнять вручную, но GetX сделает это за вас автоматически из коробки.
Интернационализация
GetX предоставляет i18n из коробки, что позволяет вам писать приложения с поддержкой различных языков.
Проверка
GetX предоставляет методы проверки для выполнения проверки ввода в ваших приложениях Flutter. Это очень удобно, так как вам не нужно устанавливать отдельный пакет проверки.
Место хранения
GetX обеспечивает быстрый, сверхлегкий и синхронный ключ-значение в памяти, который выполняет резервное копирование данных на диск при каждой операции. Он полностью написан на Dart и легко интегрируется с основным пакетом GetX.
Начало работы с GetX
Теперь, когда вы узнали, что такое GetX, какие функции и преимущества он предоставляет, давайте посмотрим, как настроить его в своем приложении. Мы создадим демонстрационное приложение, чтобы увидеть большинство функций, которые мы упомянули, в действии. Давайте начнем.
Создайте совершенно новое приложение Flutter
Мы начнем с создания нового приложения Flutter через интерфейс командной строки Flutter. Я предполагаю, что ваша машина уже настроена для разработки приложений с помощью Flutter. Итак, мы запускаем:
flutter create getx_demo
Это сгенерирует базовый код, необходимый для приложения Flutter. Затем откройте только что созданный проект в выбранном вами редакторе (в этой статье мы будем использовать VS Code). Затем мы запустим проект, чтобы убедиться, что он работает нормально (убедитесь, что у вас подключено устройство или запущен эмулятор/симулятор).
Когда приложение запустится, вы увидите приложение счетчика по умолчанию, которое Flutter формирует для вас при создании нового приложения Flutter. Что мы собираемся сделать, так это реализовать то же самое приложение-счетчик, но с GetX для управления состоянием приложения (которое является переменной count).
Мы начнем с очистки main.dart
и оставим только этот фрагмент кода:
# 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'), ); } }
К настоящему времени наше приложение было бы сломано, поскольку виджета MyHomePage
больше нет. Давайте исправим это. С GetX нам не нужны виджеты с отслеживанием состояния, а также наш пользовательский интерфейс может быть четко отделен от нашей бизнес-логики. Итак, мы создадим два каталога внутри lib/
. Эти каталоги:
views/ | Для удержания экранов в нашем приложении. |
controllers/ | Держать все контроллеры для экранов в нашем приложении. |
Давайте создадим виджет MyHomePage
внутри views/
. Имя файла будет my_home_page.dart
. После того, как вы его создадите, добавьте в него следующий фрагмент кода:
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), ), ); } }
Теперь у нас есть виджет MyHomePage
, давайте импортируем его в main.dart
. Добавьте оператор импорта в начало файла main.dart ниже import 'package:flutter/material.dart';
import './views/my_home_page.dart';
Теперь ваш файл main.dart
должен выглядеть так:
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'), ); } }
Когда вы сейчас сохраните приложение, все ошибки должны быть исправлены, и приложение запустится. Но вы заметите, что когда вы снова нажмете кнопку, счетчик не будет обновлен. Если вы посмотрите на код views/my_home_page.dart
, вы увидите, что мы просто жестко кодируем 0
в качестве значения виджета Text и передаем null
обработчику onPressed
кнопки. Давайте добавим GetX, чтобы приложение снова заработало.
Установка GetX
Перейдите на страницу установки GetX на pub.dev, и вы увидите строку кода, которую нужно скопировать и поместить в файл pubspec.yml
для установки GetX. На момент написания этой статьи текущая версия GetX — 3.23.1. Итак, мы скопируем строку:
get: ^3.23.1
А затем вставьте его в раздел dependencies
нашего файла pubspec.yml
. Когда вы сохраняете файл, get должен быть автоматически установлен для вас. Или вы можете запустить вручную в своем терминале.
flutter pub get
Раздел зависимостей вашего файла pubspec.yml
должен выглядеть так:
dependencies: flutter: sdk: flutter get: ^3.23.1
GetxController
Мы упоминали, что GetX позволяет вам отделить пользовательский интерфейс вашего приложения от логики. Он делает это, предоставляя класс GetxController
, который вы можете наследовать для создания классов контроллеров для представлений вашего приложения. Для нашего текущего приложения у нас есть одно представление, поэтому мы создадим контроллер для этого представления. Перейдите в каталог controllers/
и создайте файл с именем my_home_page_controller.dart
. Это будет содержать контроллер для представления MyHomePage
.
После создания файла сначала импортируйте пакет GetX, добавив его в начало файла:
import 'package:get/get.dart';
Затем вы создадите внутри него класс MyHomePageController
и расширите класс GetxController
. Вот как должен выглядеть файл:
import 'package:get/get.dart'; class MyHomePageController extends GetxController {}
давайте добавим состояние счетчика в созданный нами класс.
final count = 0;
В GetX сделать переменную наблюдаемой — это означает, что при ее изменении другие части нашего приложения, зависящие от нее, будут уведомлены. Для этого нам просто нужно добавить .obs
к инициализации переменной. Итак, для нашей вышеуказанной переменной count
мы добавим .obs
к 0
. Итак, приведенное выше объявление теперь будет выглядеть так:
final count = 0.obs;
Вот как на данный момент выглядит наш файл контроллера:
import 'package:get/get.dart'; class MyHomePageController extends GetxController { final count = 0.obs; }
Чтобы завершить работу с MyHomePageController
, мы реализуем метод increment
. Это фрагмент, чтобы сделать это:
increment() => count.value++;
Вы заметите, что нам нужно было добавить .value
к переменной count, чтобы увеличить ее. Мы сделали это, потому что добавление .obs
к переменной делает ее наблюдаемой переменной, а чтобы получить значение наблюдаемой переменной, вы делаете это из свойства value
.
Итак, мы закончили с контроллером. Теперь при изменении значения count любая часть нашего приложения, использующая его, будет обновляться автоматически.
Теперь мы перейдем к нашему представлению и сообщим ему о контроллере, который мы только что создали. Мы сделаем это, создав экземпляр класса контроллера с помощью функции управления зависимостями GetX. Это гарантирует, что наш контроллер не будет находиться в памяти, когда он больше не нужен.
В views/my_home_page.dart
импортируйте пакет Get, а также созданный вами контроллер следующим образом:
import 'package:get/get.dart'; import '../controllers/my_home_page_controller.dart';
Затем внутри класса MyHomePage
мы создадим экземпляр MyHomePageController
:
final MyHomePageController controller = Get.put(MyHomePageController());
Теперь у нас есть экземпляр MyHomePageController
, мы можем использовать как переменную состояния, так и метод. Итак, начиная с состояния, в GetX, чтобы пометить часть вашего пользовательского интерфейса для перестройки при изменении переменной состояния, вы оберните эту часть виджетом Obx
. GetX предоставляет другие способы сделать это, но этот метод намного проще и чище.
Для нашего приложения подсчета мы хотим, чтобы виджет «Текст» обновлялся текущим подсчетом. Итак, мы обернем виджет Text виджетом Obx
следующим образом:
Obx(() => Text('0',style: Theme.of(context).textTheme.headline4,),)
Затем мы заменим статическую строку 0
на переменную count из MyHomePageController
следующим образом:
Obx(() => Text('${controller.count.value}', ,style: Theme.of(context).textTheme.headline4,),)
Наконец, мы будем вызывать метод увеличения при нажатии floatingActionButton
следующим образом:
floatingActionButton: FloatingActionButton( onPressed: controller.increment, tooltip: 'Increment', child: Icon(Icons.add), ),
Итак, в целом, наш файл представления MyHomePage
теперь должен выглядеть так:
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), ), ); } }
Когда вы сохраняете приложение или перезапускаете его, приложение-счетчик должно работать так же, как и при первом создании приложения.
Я полагаю, вы видели, насколько интуитивно понятно управление состоянием в GetX, нам не пришлось писать много шаблонов, и эта простота будет более очевидной по мере усложнения вашего приложения. Вы также заметите, что наше представление не хранит и не поддерживает какое-либо состояние, поэтому оно может быть виджетом без состояния. Мозг представления, в свою очередь, теперь является классом контроллера, который будет хранить состояние представления и методов.
Навигация в GetX
Мы видели управление состоянием в GetX. Давайте теперь посмотрим, как GetX поддерживает навигацию в вашем приложении. Чтобы активировать функцию навигации GetX, вам нужно всего лишь внести одно изменение в main.dart
, а именно превратить виджет MaterialApp
в виджет GetMaterialApp
. Давайте сделаем это, сначала импортировав Get в начало main.dart
import 'package:get/get.dart';
Затем мы вносим изменения в MaterialApp
, чтобы наш файл main.dart
теперь выглядел так:
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'), ); } }
Теперь наше приложение настроено для поддержки навигации GetX. Чтобы проверить это, мы создадим еще одно представление в каталоге views/
. Мы вызовем это на about_page.dart
и он будет содержать следующий код:
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.', ), ), ], ), ), ); } }
Затем мы перейдем к MyHomePage
и добавим кнопку, которая при нажатии переместит нас на AboutPage
. Вот так. Кнопка должна быть под виджетом Obx. Вот:
FlatButton(onPressed: () {}, child: Text('About GetX'))
Нам также нужно будет импортировать AboutPage
поверх файла MyHomePage
:
import './about_page.dart';
Чтобы заставить GetX перейти на AboutPage
, нам нужна всего одна строка кода:
Get.to(AboutPage());
Давайте добавим это к onPressed
вызову FlatButton
виджета FlatButton следующим образом:
FlatButton( onPressed: () { Get.to(AboutPage()); }, child: Text('About GetX'))
Когда вы сохраните свое приложение сейчас, вы сможете перейти на AboutPage
.
Вы также можете заменить представление MyHomePage
на AboutPage
, чтобы пользователь не смог вернуться на предыдущую страницу, нажав кнопку возврата устройства. Это полезно для таких экранов, как экраны входа в систему. Для этого замените содержимое обработчика onPressed
приведенным ниже кодом:
Get.off(AboutPage());
Это выведет представление MyHomePage
и заменит его на AboutPage
.
Теперь, когда мы можем перейти к AboutPage
, я думаю, будет не так уж плохо иметь возможность вернуться к MyHomePage
, чтобы сделать это, мы добавим кнопку в AboutPage
после виджета Padding и в его обработчике onPressed
мы сделаем вызов на Get.back()
, чтобы вернуться к MyHomePage
:
FlatButton( onPressed: () { Get.back(); }, child: Text('Go Home') )
Снэк-бар
Во Flutter условно, чтобы показать Snackbar, вам нужно будет написать что-то вроде этого:
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);
Вы можете заметить, что мы все еще зависим от свойства context
. Давайте посмотрим, как мы можем добиться этого в GetX. Перейдите в представление MyHomePage
и добавьте еще один виджет FlatButton
под последней добавленной кнопкой. Вот фрагмент кнопки:
FlatButton( onPressed: () { // TODO: Implement Snackbar }, child: Text('Show Snackbar'))
Давайте отобразим сообщение «Yay! Потрясающая закусочная GetX». Внутри функции обработчика onPressed добавьте следующую строку кода:
Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar');
Запустите приложение, и когда вы нажмете кнопку «Показать закусочную», вы увидите закусочную поверх вашего приложения!
Посмотрите, как мы уменьшили количество строк, необходимых для отображения закусочной в приложении Flutter? Давайте еще немного настроим Snackbar; Давайте сделаем так, чтобы он отображался в нижней части приложения. Измените код на этот:
Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar',snackPosition:SnackPosition.BOTTOM, );
Сохраните и запустите ваше приложение, и Snackbar теперь появится в нижней части приложения. Как насчет того, чтобы изменить цвет фона Snackbar, так как в данный момент он прозрачен. Мы изменим его на цвет amberAccent
из класса Colors
во Flutter. Обновите код до этого:
Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar',snackPosition:SnackPosition.BOTTOM, backgroundColor: Colors.amberAccent );
В целом код кнопки должен выглядеть так:
FlatButton( onPressed: () { Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.amberAccent); }, child: Text('Show Snackbar'))
Диалог
GetX предоставляет простой метод создания AlertDialog во Flutter. Давайте посмотрим на это в действии. Создайте еще одну кнопку ниже предыдущей:
FlatButton( onPressed: () { // TODO: Show alert dialog }, child: Text('Show AlertDialog'))
Давайте вызовем GetX для отображения диалогового окна предупреждения:
Get.defaultDialog();
Это покажет диалоговое окно предупреждений по умолчанию, которое можно закрыть, нажав за пределами диалогового окна. Вы можете видеть, как в одной строке кода у нас есть рабочий диалог предупреждений. Давайте немного настроим его. Давайте изменим заголовок и сообщение:
Get.defaultDialog( title: 'GetX Alert', middleText: 'Simple GetX alert');
Сохраните и запустите свое приложение, и вы увидите изменения, когда нажмете кнопку «Show AlertDialog». Мы можем добавить кнопки подтверждения и отмены следующим образом:
Get.defaultDialog( title: 'GetX Alert', middleText: 'Simple GetX alert', textConfirm: 'Okay', confirmTextColor: Colors.amberAccent, textCancel: 'Cancel');
Есть много способов настроить диалоговое окно GetX, а API довольно интуитивно понятен и прост.
Заключение
GetX был создан для повышения производительности разработчиков Flutter при создании новых функций. Вместо того, чтобы искать шаблоны, необходимые для таких вещей, как управление состоянием, управление навигацией и т. д., GetX предоставляет простой интуитивно понятный API для выполнения этих действий без ущерба для производительности. В этой статье вы познакомитесь с GetX и узнаете, как начать использовать его в своих приложениях Flutter.
- Вы можете найти демо здесь →