get_ex 1.0.1 copy "get_ex: ^1.0.1" to clipboard
get_ex: ^1.0.1 copied to clipboard

State management, DI, and navigation for Flutter. Reactive Rx types, controllers, routing, transitions, snackbars, dialogs, i18n, and theming with zero external dependencies.

example/lib/main.dart

// Complete example app demonstrating get_x features:
// - Counter with Rx reactive state
// - Todo list with GetXController + RxList
// - Named routing with middleware
// - DI bindings
// - Snackbar and dialog
// - Internationalization
import 'package:flutter/material.dart';
import 'package:get_ex/get_ex.dart';

// ---------------------------------------------------------------------------
// Translations
// ---------------------------------------------------------------------------

class AppTranslations extends GetXTranslations {
  @override
  Map<String, Map<String, String>> get keys => {
        'en_US': {
          'title': 'GetX Example',
          'counter': 'Counter',
          'todos': 'Todos',
          'increment': 'Increment',
          'add_todo': 'Add Todo',
          'greeting': 'Hello @name!',
          'switch_lang': 'Switch to Spanish',
        },
        'es_ES': {
          'title': 'Ejemplo GetX',
          'counter': 'Contador',
          'todos': 'Tareas',
          'increment': 'Incrementar',
          'add_todo': 'Agregar Tarea',
          'greeting': '¡Hola @name!',
          'switch_lang': 'Cambiar a Inglés',
        },
      };
}

// ---------------------------------------------------------------------------
// Controllers
// ---------------------------------------------------------------------------

class CounterController extends GetXController {
  final count = 0.obs;

  late GetXWorker _logWorker;

  @override
  void onInit() {
    super.onInit();
    _logWorker = ever(count, (val) {
      GetXLog.info('Counter changed to $val');
    });
  }

  void increment() => count.value++;
  void decrement() => count.value--;

  @override
  void onClose() {
    _logWorker.dispose();
    super.onClose();
  }
}

class TodoController extends GetXController {
  final todos = <String>[].obs;
  final textController = TextEditingController();

  void addTodo() {
    final text = textController.text.trim();
    if (text.isNotEmpty) {
      todos.add(text);
      textController.clear();
    }
  }

  void removeTodo(int index) => todos.removeAt(index);

  @override
  void onClose() {
    textController.dispose();
    super.onClose();
  }
}

// ---------------------------------------------------------------------------
// Bindings
// ---------------------------------------------------------------------------

class HomeBinding extends GetXBindings {
  @override
  void dependencies() {
    GetX.lazyPut(() => CounterController());
  }
}

class TodoBinding extends GetXBindings {
  @override
  void dependencies() {
    GetX.lazyPut(() => TodoController());
  }
}

// ---------------------------------------------------------------------------
// Middleware
// ---------------------------------------------------------------------------

class LogMiddleware extends GetXMiddleware {
  @override
  int get priority => 0;

  @override
  GetXPage? onPageCalled(GetXPage? page) {
    GetXLog.info('Navigating to: ${page?.name}');
    return page;
  }
}

// ---------------------------------------------------------------------------
// Pages
// ---------------------------------------------------------------------------

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('title'.tr),
        actions: [
          IconButton(
            icon: const Icon(Icons.language),
            onPressed: () {
              final isEnglish =
                  GetXLocale.currentLocale.languageCode == 'en';
              GetX.updateLocale(
                isEnglish
                    ? const Locale('es', 'ES')
                    : const Locale('en', 'US'),
              );
            },
          ),
          IconButton(
            icon: const Icon(Icons.brightness_6),
            onPressed: () {
              GetX.changeThemeMode(
                GetX.isDarkMode ? ThemeMode.light : ThemeMode.dark,
              );
            },
          ),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              'greeting'.trParams({'name': 'Developer'}),
              style: Theme.of(context).textTheme.headlineSmall,
            ),
            const SizedBox(height: 32),
            ElevatedButton(
              onPressed: () => GetX.toNamed('/counter'),
              child: Text('counter'.tr),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () => GetX.toNamed('/todos'),
              child: Text('todos'.tr),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                GetX.snackbar(
                  context,
                  'Hello!',
                  'This is a GetX snackbar',
                  snackPosition: GetXSnackPosition.top,
                  backgroundColor: Colors.blueAccent,
                );
              },
              child: const Text('Show Snackbar'),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                GetX.defaultDialog(
                  context,
                  title: 'GetX Dialog',
                  content: const Text('This is a default dialog.'),
                  textConfirm: 'OK',
                  textCancel: 'Cancel',
                  onConfirm: () => GetXLog.info('Confirmed!'),
                );
              },
              child: const Text('Show Dialog'),
            ),
          ],
        ),
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  const CounterPage({super.key});

  @override
  Widget build(BuildContext context) {
    final controller = GetX.find<CounterController>();

    return Scaffold(
      appBar: AppBar(title: Text('counter'.tr)),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            obx(() => Text(
                  '${controller.count.value}',
                  style: Theme.of(context).textTheme.displayLarge,
                )),
            const SizedBox(height: 24),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                FloatingActionButton(
                  heroTag: 'decrement',
                  onPressed: controller.decrement,
                  child: const Icon(Icons.remove),
                ),
                const SizedBox(width: 16),
                FloatingActionButton(
                  heroTag: 'increment',
                  onPressed: controller.increment,
                  child: const Icon(Icons.add),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

class TodoPage extends StatelessWidget {
  const TodoPage({super.key});

  @override
  Widget build(BuildContext context) {
    final controller = GetX.find<TodoController>();

    return Scaffold(
      appBar: AppBar(title: Text('todos'.tr)),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16),
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: controller.textController,
                    decoration: InputDecoration(
                      hintText: 'add_todo'.tr,
                      border: const OutlineInputBorder(),
                    ),
                    onSubmitted: (_) => controller.addTodo(),
                  ),
                ),
                const SizedBox(width: 8),
                IconButton(
                  icon: const Icon(Icons.add),
                  onPressed: controller.addTodo,
                ),
              ],
            ),
          ),
          Expanded(
            child: obx(() => ListView.builder(
                  itemCount: controller.todos.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text(controller.todos[index]),
                      trailing: IconButton(
                        icon: const Icon(Icons.delete),
                        onPressed: () => controller.removeTodo(index),
                      ),
                    );
                  },
                )),
          ),
        ],
      ),
    );
  }
}

// ---------------------------------------------------------------------------
// Main
// ---------------------------------------------------------------------------

void main() {
  GetX.config(enableLog: true);

  runApp(
    GetXApp(
      title: 'GetX Example',
      initialRoute: '/',
      translations: AppTranslations(),
      locale: const Locale('en', 'US'),
      fallbackLocale: const Locale('en', 'US'),
      theme: ThemeData.light(useMaterial3: true),
      darkTheme: ThemeData.dark(useMaterial3: true),
      themeMode: ThemeMode.system,
      debugShowCheckedModeBanner: false,
      pages: [
        GetXPage(
          name: '/',
          page: () => const HomePage(),
          middlewares: [LogMiddleware()],
        ),
        GetXPage(
          name: '/counter',
          page: () => const CounterPage(),
          binding: HomeBinding(),
          transition: GetXTransition.fade,
          middlewares: [LogMiddleware()],
        ),
        GetXPage(
          name: '/todos',
          page: () => const TodoPage(),
          binding: TodoBinding(),
          transition: GetXTransition.rightToLeft,
          middlewares: [LogMiddleware()],
        ),
      ],
    ),
  );
}
0
likes
155
points
22
downloads

Documentation

Documentation
API reference

Publisher

unverified uploader

Weekly Downloads

State management, DI, and navigation for Flutter. Reactive Rx types, controllers, routing, transitions, snackbars, dialogs, i18n, and theming with zero external dependencies.

Repository (GitHub)
View/report issues

Topics

#state-management #dependency-injection #navigation #reactive #getx

License

MIT (license)

Dependencies

flutter

More

Packages that depend on get_ex