Answer
Overview
GetX is an all-in-one Flutter package that provides state management, dependency injection, and route management in a lightweight, reactive way.
GetX Setup
yamldependencies: get: ^4.6.6
dartvoid main() { runApp(GetMaterialApp( title: 'GetX App', initialRoute: '/', getPages: AppPages.routes, // onGenerateRoute equivalent home: HomeScreen(), )); }
onGenerateRoute Equivalent in GetX
GetX uses
text
GetMaterialApptext
getPagestext
onGenerateRoutedart// routes/app_pages.dart class AppPages { static final routes = [ GetPage(name: '/', page: () => HomeScreen()), GetPage(name: '/login', page: () => LoginScreen()), GetPage( name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding(), // DI for this route middlewares: [AuthMiddleware()], // Route guards ), GetPage( name: '/product/:id', // Dynamic route parameter page: () => ProductDetailScreen(), ), ]; } // Navigate by name Get.toNamed('/profile'); Get.toNamed('/product/123'); Get.offAllNamed('/login'); // Clear stack and go to login
GetxController with onInit / onClose
dartclass HomeController extends GetxController { // Reactive state final count = 0.obs; final isLoading = false.obs; final items = <String>[].obs; void onInit() { super.onInit(); // Called when controller is first created fetchData(); ever(count, (_) => print('Count changed: $count')); } void onReady() { super.onReady(); // Called after the widget is rendered on screen // Good for dialogs, navigation after build } void onClose() { // Called when controller is removed from memory // Clean up: close streams, cancel subscriptions super.onClose(); } Future<void> fetchData() async { isLoading.value = true; await Future.delayed(Duration(seconds: 2)); items.addAll(['Item 1', 'Item 2', 'Item 3']); isLoading.value = false; } void increment() => count.value++; }
Using the Controller in Widget
dartclass HomeScreen extends StatelessWidget { final controller = Get.put(HomeController()); // Register + get Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('GetX Demo')), body: Obx(() => // Rebuilds when observable changes controller.isLoading.value ? CircularProgressIndicator() : ListView.builder( itemCount: controller.items.length, itemBuilder: (_, i) => ListTile(title: Text(controller.items[i])), ), ), floatingActionButton: FloatingActionButton( onPressed: controller.increment, child: Obx(() => Text('${controller.count}')), ), ); } }
GetX Workers (Reactive Listeners in onInit)
dartvoid onInit() { super.onInit(); // ever — runs every time value changes ever(count, (val) => print('Changed to $val')); // once — runs only on first change once(count, (_) => print('First change!')); // debounce — runs after 500ms of no changes debounce(searchQuery, (_) => search(), time: Duration(milliseconds: 500)); // interval — runs at most every 1 second interval(counter, (_) => save(), time: Duration(seconds: 1)); }
Three GetX State Management Approaches
dart// 1. Reactive (Obx + .obs) — auto-rebuilds final name = 'Alice'.obs; Obx(() => Text(name.value)); // 2. Simple (GetBuilder + update()) — manual refresh class MyController extends GetxController { int count = 0; void increment() { count++; update(); } // Call update() to rebuild } GetBuilder<MyController>(builder: (c) => Text('${c.count}')); // 3. MixinBuilder — hybrid of both GetX<MyController>(builder: (c) => Text('${c.count.value}'));
Summary: GetX provides
(setup),textonInit(post-build), andtextonReady(teardown). UsetextonClosewithtextGetMaterialAppfor named routing, andtextgetPages+text.obsfor reactive state.textObx