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

Lightweight Flutter state management and dependency injection extracted from GetX. Includes reactive variables (.obs, Obx), simple state (GetBuilder, GetxController), DI (Get.put / Get.find / lazyPut) [...]

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:get_light/get_light.dart';

// ─────────────────────────────────────────────
// Controllers
// ─────────────────────────────────────────────

/// Reactive counter using .obs — UI updates via Obx.
class ReactiveController extends GetxController {
  final count = 0.obs;
  final history = RxList<String>();

  Worker? _historyWorker;

  @override
  void onInit() {
    super.onInit();
    // ever: runs on every change
    _historyWorker = ever(count, (value) {
      history.add('count → $value');
      if (history.length > 5) history.removeAt(0);
    });
  }

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

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

/// Simple counter using update() — UI updates via GetBuilder.
class SimpleController extends GetxController {
  int count = 0;

  void increment() {
    count++;
    update();
  }

  void decrement() {
    count--;
    update();
  }
}

/// A service registered as a permanent singleton.
class AppService extends GetxService {
  final sessionId = DateTime.now().millisecondsSinceEpoch;

  String get info => 'Session #$sessionId';
}

// ─────────────────────────────────────────────
// App entry point
// ─────────────────────────────────────────────

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  Get.put(AppService(), permanent: true);
  runApp(const GetLightExampleApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'get_light example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}

// ─────────────────────────────────────────────
// Home — tab controller
// ─────────────────────────────────────────────

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

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('get_light example'),
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          bottom: const TabBar(
            tabs: [
              Tab(icon: Icon(Icons.bolt), text: 'Reactive'),
              Tab(icon: Icon(Icons.widgets), text: 'Simple'),
              Tab(icon: Icon(Icons.storage), text: 'DI'),
            ],
          ),
        ),
        body: const TabBarView(
          children: [
            ReactiveTab(),
            SimpleTab(),
            DiTab(),
          ],
        ),
      ),
    );
  }
}

// ─────────────────────────────────────────────
// Tab 1 — Reactive (Obx + .obs)
// ─────────────────────────────────────────────

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

  @override
  Widget build(BuildContext context) {
    // GetBuilder registers & exposes the controller
    return GetBuilder<ReactiveController>(
      init: ReactiveController(),
      builder: (_) => _ReactiveBody(),
    );
  }
}

class _ReactiveBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final ctrl = Get.find<ReactiveController>();

    return Padding(
      padding: const EdgeInsets.all(24),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Text('Reactive counter (.obs + Obx)',
              style: TextStyle(fontWeight: FontWeight.bold)),
          const SizedBox(height: 24),

          // Obx rebuilds only this Text when count changes
          Obx(() => Text(
                '${ctrl.count}',
                style: Theme.of(context).textTheme.displayLarge,
              )),

          const SizedBox(height: 24),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              FilledButton.icon(
                onPressed: ctrl.decrement,
                icon: const Icon(Icons.remove),
                label: const Text('−'),
              ),
              const SizedBox(width: 12),
              OutlinedButton(
                onPressed: ctrl.reset,
                child: const Text('Reset'),
              ),
              const SizedBox(width: 12),
              FilledButton.icon(
                onPressed: ctrl.increment,
                icon: const Icon(Icons.add),
                label: const Text('+'),
              ),
            ],
          ),

          const SizedBox(height: 32),
          const Text('Change history (ever worker)',
              style: TextStyle(fontWeight: FontWeight.bold)),
          const SizedBox(height: 8),

          // Obx for the history list
          Obx(() => Column(
                children: ctrl.history
                    .map((e) => Text(e, style: const TextStyle(fontSize: 12)))
                    .toList(),
              )),
        ],
      ),
    );
  }
}

// ─────────────────────────────────────────────
// Tab 2 — Simple state (GetBuilder + update())
// ─────────────────────────────────────────────

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

  @override
  Widget build(BuildContext context) {
    return GetBuilder<SimpleController>(
      init: SimpleController(),
      builder: (ctrl) => Padding(
        padding: const EdgeInsets.all(24),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('Simple counter (GetBuilder + update())',
                style: TextStyle(fontWeight: FontWeight.bold)),
            const SizedBox(height: 24),
            Text(
              '${ctrl.count}',
              style: Theme.of(context).textTheme.displayLarge,
            ),
            const SizedBox(height: 24),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                FilledButton.icon(
                  onPressed: ctrl.decrement,
                  icon: const Icon(Icons.remove),
                  label: const Text('−'),
                ),
                const SizedBox(width: 24),
                FilledButton.icon(
                  onPressed: ctrl.increment,
                  icon: const Icon(Icons.add),
                  label: const Text('+'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

// ─────────────────────────────────────────────
// Tab 3 — Dependency Injection
// ─────────────────────────────────────────────

class DiTab extends StatefulWidget {
  const DiTab({super.key});

  @override
  State<DiTab> createState() => _DiTabState();
}

class _DiTabState extends State<DiTab> {
  String _log = '';

  void _appendLog(String line) => setState(() => _log += '$line\n');

  void _demoPut() {
    Get.put('Hello from Get.put!', tag: 'demo');
    final value = Get.find<String>(tag: 'demo');
    _appendLog('put → found: "$value"');
  }

  void _demoLazyPut() {
    var built = false;
    Get.lazyPut<int>(() {
      built = true;
      return 42;
    }, tag: 'lazy');
    _appendLog('lazyPut registered. built before find: $built');
    final value = Get.find<int>(tag: 'lazy');
    _appendLog('find → value: $value (now built: true)');
  }

  void _demoService() {
    final svc = Get.find<AppService>();
    _appendLog('AppService: ${svc.info}');
  }

  void _demoDelete() {
    if (Get.isRegistered<String>(tag: 'demo')) {
      Get.delete<String>(tag: 'demo');
      _appendLog('Deleted "demo" String.');
    } else {
      _appendLog('Nothing to delete (run "put" first).');
    }
  }

  void _clearLog() => setState(() => _log = '');

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(24),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          const Text('Dependency Injection',
              style: TextStyle(fontWeight: FontWeight.bold)),
          const SizedBox(height: 16),
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: [
              FilledButton(onPressed: _demoPut, child: const Text('Get.put')),
              FilledButton(
                  onPressed: _demoLazyPut, child: const Text('lazyPut')),
              FilledButton(
                  onPressed: _demoService, child: const Text('Service')),
              FilledButton(
                  onPressed: _demoDelete, child: const Text('delete')),
              OutlinedButton(
                  onPressed: _clearLog, child: const Text('Clear')),
            ],
          ),
          const SizedBox(height: 16),
          Expanded(
            child: Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: Colors.black87,
                borderRadius: BorderRadius.circular(8),
              ),
              child: SingleChildScrollView(
                child: Text(
                  _log.isEmpty ? 'Tap a button to see output…' : _log,
                  style: const TextStyle(
                      color: Colors.greenAccent,
                      fontFamily: 'monospace',
                      fontSize: 13),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
1
likes
135
points
110
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Lightweight Flutter state management and dependency injection extracted from GetX. Includes reactive variables (.obs, Obx), simple state (GetBuilder, GetxController), DI (Get.put / Get.find / lazyPut), and workers (ever, once, debounce, interval).

Repository (GitHub)
View/report issues

Topics

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

License

MIT (license)

Dependencies

flutter

More

Packages that depend on get_light