GetX: ключови понятия, навигация и DI в Flutter

Автор: IT Sectr Публикувано: 2026-02-19 Време за четене: 7 мин

GetX — лек микро-фреймуърк за Flutter, който обединява управление на състоянието, навигация и инжектиране на зависимости в един пакет. Разработен от Амир Хосейн Абдорашиди, GetX предлага минимален boilerplate: без Stream, без ChangeNotifier, без BuildContext за навигация. Според данните на pub.dev, GetX е събрал над 13 хиляди харесвания, превръщайки се в един от най-популярните Flutter пакети.

Основни точки

  • Obx — реактивен widget, който се преизгражда при промяна на Rx-променлива
  • GetController — клас за бизнес логика с методи и Rx-променливи
  • Get.to — навигация без BuildContext чрез именувани маршрути
  • Get.put / Get.find — инжектиране и получаване на зависимости чрез DI-контейнер
  • Rx-променливи — реактивни обвивки (RxInt, RxString, RxBool) с автоматично уведомяване

Какво е GetX?

GetX — all-in-one микро-фреймуърк за Flutter, който решава три основни задачи за разработка: управление на състоянието (State Management), навигация (Routing) и инжектиране на зависимости (DI). GetX не изисква Stream, ChangeNotifier, Builder или абонаменти — цялата реактивност се осигурява от Rx-обвивки, базирани на GetValue и GetStream, които работят десетки пъти по-бързо от ChangeNotifier.

GetX се позиционира като алтернатива на комбинацията Provider + Navigator + get_it/kiwi. Вместо да инсталирате три различни пакета и да пишете 10 реда конфигурация, GetX дава всичко в една кутия с един ред: GetMaterialApp вместо MaterialApp. Навигацията работи чрез Get.to(NextScreen()) без BuildContext, а DI — чрез Get.put(Service()) без Provider дърво.

Според Flutter Community Survey 2025, GetX се използва в 43% от Flutter проектите. Основни причини за избор: минимален праг за влизане (5 минути за научаване), липса на boilerplate (кодът се съкращава с 60-70% в сравнение с Provider или BLoC) и бърза MVP разработка. Критиците посочват нарушаване на принципа за разделяне на отговорностите и трудност при отстраняване на грешки.

Реактивно състояние: Obx и Rx

Obx — реактивният widget на GetX, който се преизгражда при промяна на Rx-променливи. Obx не изисква абонамент, dispose или Builder функции — достатъчно е да увиете widget в Obx и да използвате Rx-променлива вътре. Obx автоматично следи кои Rx-променливи се използват и прерисува само при тяхната промяна.

Dart
class CounterController extends GetxController {
  final count = 0.obs;
  void increment() => count++;
}

class CounterScreen extends StatelessWidget {
  final controller = Get.put(CounterController());

  @override
  Widget build(context) => Obx(() => Text('${controller.count}'));
}

Rx-променливи: .obs — getter, който увива всяка стойност в Rx-обект. GetX предоставя типизирани Rx-класове: RxInt, RxString, RxDouble, RxBool, RxList, RxMap. Всички Rx-променливи се държат като обикновени примитиви: count++, name.value = 'Hello', items.add(item). Промяната автоматично уведомява Obx абонатите.

GetBuilder — алтернатива на Obx без Rx, работеща чрез ръчно извикване на update(). GetBuilder.filter — за точково обновяване по ID ключове. Obx е по-бърз (автоматично проследяване на зависимости), GetBuilder е по-предвидим (изрично извикване на обновяване). Obx се препоръчва за прости сценарии, а GetBuilder за сложни widget-ове с множество зависимости.

GetController и жизнен цикъл

GetxController — базов клас за бизнес логика с поддръжка на жизнен цикъл. GetxController има методи: onInit() (инициализация), onReady() (след първия кадър), onClose() (почистване на ресурси). За разлика от ChangeNotifier и StateNotifier, GetxController автоматично управлява абонаментите: при унищожаване на страницата, всички Rx-променливи и Workers се отписват.

Dart
class AuthController extends GetxController {
  final user = Rx<User?>(null);
  final isLoading = false.obs;

  @override
  void onInit() {
    ever(isLoading, (_) => print('Loading: $isLoading'));
    super.onInit();
  }

  Future<void> login(String email, String password) async {
    isLoading.value = true;
    user.value = await api.login(email, password);
    isLoading.value = false;
  }
}

Workers — реактивни инструменти на GetX: ever (извиква се при всяка промяна), once (само при първата промяна), debounce (със закъснение), interval (не по-често от N пъти в секунда). Workers решават типични задачи: валидация на полета (debounce), аналитика (once), синхронизация (ever). Workers автоматично се отписват при извикване на onClose(), предотвратявайки изтичане на памет.

Навигация GetX не изисква BuildContext за преход между екрани. Вместо Navigator.push(context, MaterialPageRoute(...)) се използва Get.to(NextScreen()) — извикване от всяко място, включително Controller без достъп до BuildContext. GetX поддържа именувани маршрути, анимации, middleware и предаване на аргументи без MaterialPageRoute.

Dart
// Обикновена навигация
Get.to(ProfileScreen());
Get.back();
Get.off(LoginScreen()); // замени текущия маршрут
Get.offAll(HomeScreen()); // изчисти стека

// Именувани маршрути
Get.toNamed('/profile', arguments: 'user123');
Get.offNamed('/login');

// Middleware
GetPage(
  name: '/profile',
  page: () => ProfileScreen(),
  middlewares: [AuthMiddleware()],
)

GetPage и GetPages: GetX използва GetPages вместо routes в MaterialApp. Middleware — проверка на оторизация, пренасочвания, аналитика преди влизане на екрана. Transition — вградени преходни анимации: fadeIn, zoom, leftToRight, topToBottom. Bindings — клас, който инициализира Controller и зависимости при влизане на маршрута. Bindings решават проблема с мързелива инициализация: Controller се създава само когато екранът е отворен.

Инжектиране на зависимости с GetX

Get.put — регистрация на инстанция в DI-контейнера. Get.find — получаване на инстанция от контейнера. Get.lazyPut — мързелива инициализация (създава се при първото извикване на find). Get.putAsync — асинхронна инициализация (за услуги с init). Get.delete — изтриване от контейнера (автоматично се извиква от Bindings при унищожаване на маршрута).

МетодКога се създаваКога се изтрива
Get.putВеднагаGet.delete или onClose
Get.lazyPutПри първия findGet.delete или onClose
Get.putAsyncСлед изпълнение на FutureGet.delete или onClose
Get.createПри всеки find (нова фабрика)Не

GetX DI — най-простият DI-контейнер във Flutter. Без Provider дърво, без Module, без Scope. Get.put(Repository()) в Controller или main.dart прави обекта достъпен навсякъде в приложението чрез Get.find<Repository>(). GetX DI също поддържа етикетиране (tag: 'api') и постоянство (permanent: true) за предотвратяване на изтриване.

GetX: best practices и производителност

Производителността на GetX се основава на Rx-обвивки, работещи чрез GetStream — собствена имплементация на Stream, оптимизирана за Flutter. Според бенчмарковете на GetX, Rx-променливите са 2-3 пъти по-бързи от ChangeNotifier и 5-7 пъти по-бързи от BLoC при чести обновявания (30+ fps). GetX не използва BuildContext за абонаменти, което елиминира преизграждането на дървото от widget-ове при навигация.

Best practices: използвайте GetBuilder вместо Obx за widget-ове с голям брой дъщерни елементи (списъци, таблици). Разделяйте Controller-ите по функционални модули, а не един огромен Controller на страница. Използвайте Bindings за инициализация на Controller, а не Get.put в build метода. GetView — съкратен StatelessWidget с достъп до Controller чрез controller без Get.find.

Известни ограничения: GetX използва глобални променливи (Get.find, Get.to), което може да затрудни тестването. Mock-ване на зависимости чрез GetX изисква Get.replace() или Get.reset() между тестовете. За изолация се препоръчва Get.testMode = true. GetX не се препоръчва за приложения, изискващи строга архитектура с ясни граници на слоеве — в този случай са за предпочитане BLoC или Riverpod с кодогенериране.

Често задавани въпроси

С какво GetX се различава от Provider?

GetX — микро-фреймуърк със собствен DI, навигация и Rx-реактивност. Provider — само управление на състоянието чрез ChangeNotifier и InheritedWidget. GetX не изисква BuildContext, има вградена навигация и DI, намалява boilerplate с 60-70%. Provider използва стандартния Flutter Navigator и изисква външни решения за DI. GetX е по-бърз в разработката, Provider — по-близо до родния Flutter API.

Какво са GetX Workers?

Workers — инструменти за реактивна обработка на промени на Rx-променливи. ever — callback при всяка промяна, once — само при първата, debounce — със закъснение (за поле за търсене), interval — не по-често от N пъти (за аналитика). Workers се декларират в onInit() на GetxController и автоматично се отписват в onClose(). Това замества ръчното addListener/removeListener с ChangeNotifier.

Как да тестваме GetX?

GetX предоставя Get.testMode = true за активиране на тестов режим. Зависимостите се заменят чрез Get.replace<Service>(mockService). Между тестовете се извиква Get.reset() за почистване на DI-контейнера. Controller-ите се тестват директно без Flutter: final c = CounterController(); c.increment(); expect(c.count.value, 1). За widget-ове с Obx използвайте tester.pumpWidget с InjectMocker.

Струва ли си да използваме GetX за големи проекти?

GetX е подходящ за проекти от всякакъв размер, но изисква дисциплина. За големи проекти (10+ екрана) използвайте: Bindings за изолация на Controller-и, модули (GetPages файлове по функционалност), GetView вместо ръчен Get.find в build. Основният риск — злоупотреба с глобален достъп (Get.find навсякъде). Стриктни code review и архитектурни насоки решават този проблем. Много продакшън приложения с милиони потребители работят на GetX.

Какво са GetX Bindings?

Bindings — клас, който свързва маршрута с неговите зависимости. При влизане на екрана, Binding създава Controller и услугите чрез Get.lazyPut, при излизане — ги изтрива. Bindings имплементират мързелива инициализация: Controller не съществува в паметта, докато екранът не бъде отворен. Това спестява RAM и време за стартиране на приложението. Декларира се в GetPage: GetPage(name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding()).

Резюме

  • GetX — Flutter микро-фреймуърк с управление на състоянието, навигация и DI в един пакет
  • Obx и Rx — реактивни обвивки с автоматично прерисуване без Stream и ChangeNotifier
  • GetxController — клас за бизнес логика с жизнен цикъл onInit/onReady/onClose
  • Get.to / Get.back — навигация без BuildContext с вградени анимации
  • Get.put / Get.find — DI-контейнер без Provider дърво с мързелива инициализация
  • Workers — ever, once, debounce, interval за реактивна обработка на промени
  • Bindings — мързелива инициализация на Controller при отваряне на маршрут с автоматично освобождаване

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също