GetX — лек микро-фреймуърк за Flutter, който обединява управление на състоянието, навигация и инжектиране на зависимости в един пакет. Разработен от Амир Хосейн Абдорашиди, GetX предлага минимален boilerplate: без Stream, без ChangeNotifier, без BuildContext за навигация. Според данните на pub.dev, GetX е събрал над 13 хиляди харесвания, превръщайки се в един от най-популярните Flutter пакети.
Основни точки
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 — реактивният widget на GetX, който се преизгражда при промяна на Rx-променливи. Obx не изисква абонамент, dispose или Builder функции — достатъчно е да увиете widget в Obx и да използвате Rx-променлива вътре. Obx автоматично следи кои Rx-променливи се използват и прерисува само при тяхната промяна.
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-ове с множество зависимости.
GetxController — базов клас за бизнес логика с поддръжка на жизнен цикъл. GetxController има методи: onInit() (инициализация), onReady() (след първия кадър), onClose() (почистване на ресурси). За разлика от ChangeNotifier и StateNotifier, GetxController автоматично управлява абонаментите: при унищожаване на страницата, всички Rx-променливи и Workers се отписват.
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.
// Обикновена навигация
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 се създава само когато екранът е отворен.
Get.put — регистрация на инстанция в DI-контейнера. Get.find — получаване на инстанция от контейнера. Get.lazyPut — мързелива инициализация (създава се при първото извикване на find). Get.putAsync — асинхронна инициализация (за услуги с init). Get.delete — изтриване от контейнера (автоматично се извиква от Bindings при унищожаване на маршрута).
| Метод | Кога се създава | Кога се изтрива |
|---|---|---|
| Get.put | Веднага | Get.delete или onClose |
| Get.lazyPut | При първия find | Get.delete или onClose |
| Get.putAsync | След изпълнение на Future | Get.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 се основава на 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 — микро-фреймуърк със собствен DI, навигация и Rx-реактивност. Provider — само управление на състоянието чрез ChangeNotifier и InheritedWidget. GetX не изисква BuildContext, има вградена навигация и DI, намалява boilerplate с 60-70%. Provider използва стандартния Flutter Navigator и изисква външни решения за DI. GetX е по-бърз в разработката, Provider — по-близо до родния Flutter API.
Workers — инструменти за реактивна обработка на промени на Rx-променливи. ever — callback при всяка промяна, once — само при първата, debounce — със закъснение (за поле за търсене), interval — не по-често от N пъти (за аналитика). Workers се декларират в onInit() на GetxController и автоматично се отписват в onClose(). Това замества ръчното addListener/removeListener с ChangeNotifier.
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 е подходящ за проекти от всякакъв размер, но изисква дисциплина. За големи проекти (10+ екрана) използвайте: Bindings за изолация на Controller-и, модули (GetPages файлове по функционалност), GetView вместо ръчен Get.find в build. Основният риск — злоупотреба с глобален достъп (Get.find навсякъде). Стриктни code review и архитектурни насоки решават този проблем. Много продакшън приложения с милиони потребители работят на GetX.
Bindings — клас, който свързва маршрута с неговите зависимости. При влизане на екрана, Binding създава Controller и услугите чрез Get.lazyPut, при излизане — ги изтрива. Bindings имплементират мързелива инициализация: Controller не съществува в паметта, докато екранът не бъде отворен. Това спестява RAM и време за стартиране на приложението. Декларира се в GetPage: GetPage(name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding()).
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също