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 — реактивни виџет GetX-а који се преграђује при промени Rx-променљивих. Obx не захтева претплату, dispose или Builder-функције — довољно је умотати виџет у 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 — гетер који умотава било коју вредност у 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 за сложене виџете са више зависности.
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 за претплате, што елиминише преграђивање стабла виџета при навигацији.
Best practices: користите GetBuilder уместо Obx за виџете са великим бројем дечијих елемената (листе, табеле). Раздвајајте Controller-е по функционалним модулима, а не један огроман Controller по страници. Користите Bindings за иницијализацију Controller-а, а не Get.put у build-методу. GetView — скраћени StatelessWidget са приступом Controller-у кроз controller без Get.find.
Позната ограничења: GetX користи глобалне променљиве (Get.find, Get.to), што може отежати тестирање. Моковање зависности кроз 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 — повратни позив при свакој промени, 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). За виџете са 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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође