7

I wonder how to use multiple getx controllers in flutter.
Even if the data is updated, it is not reflected in real time.
and Getbuilder can only use one controller.
Can you give me an example of the code?

Code example

class Controller1 extends GetxController {
  int counter = 0;

  void addCounter() {
    counter++;
    update();
  }
}

class Controller2 extends GetxController {
  int counter = 0;

  void addCounter() {
    counter++;
    update();
  }
}

class CounterView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    Controller1 controller1 = Get.find();
    Controller2 controller2 = Get.find();

    return Text(
      '${controller1.counter} / ${controller2.counter}'
    );
  }
}

class CounterButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    Controller1 controller1 = Get.find();
    Controller2 controller2 = Get.find();

    return Column(
      children: [
        GestureDetector(
          onTap: () => controller1.addCounter(),
          child: ...
        );
        GestureDetector(
          onTap: () => controller2.addCounter(),
          child: ...
        );
      ]
    );
  }
}
Damian
  • 109
  • 1
  • 1
  • 7

2 Answers2

3

I have alternative solution.

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

class Controller1 extends GetxController {
  int counter = 0;

  void addCounter() {
    counter++;
    update();
  }
}

class Controller2 extends GetxController {
  int counter = 0;

  void addCounter() {
    counter++;
    update();
  }
}

class CounterView extends GetView {
  const CounterView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    Get.put(Controller1());
    Get.put(Controller2());
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          children: [
            GetBuilder<Controller1>(
              builder: (controller1) => GestureDetector(
                onTap: () => controller1.addCounter(),
                child: const Text(
                    //controller1.counter.toString(),
                    "Controller-1"),
              ),
            ),
            GetBuilder<Controller2>(
              builder: (controller2) => GestureDetector(
                onTap: () => controller2.addCounter(),
                child: const Text(
                    //controller2.counter.toString(),
                    "Controller-2"),
              ),
            ),
            const SizedBox(
              height: 10,
            ),
            GetBuilder<Controller1>(
              builder: (controller1) => GetBuilder<Controller2>(
                builder: (controller2) => Column(
                  children: [
                    Text(
                      "Controller-1 = " + controller1.counter.toString(),
                    ),
                    Text(
                      "Controller-2 = " + controller2.counter.toString(),
                    ),
                    Text(
                      "C1 / C2 = " +
                          (controller1.counter / controller2.counter)
                              .toString(),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Update:- Using Obx@StatelessWidget

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

void main() {
  runApp(
    GetMaterialApp(
      home: MyWidget(),
    ),
  );
}
class Controller1 extends GetxController {
  final counter = 0.obs;
  void addCounter() {
    counter.value++;
  }
}

class Controller2 extends GetxController {
  final counter = 0.obs;
  void addCounter() {
    counter.value++;
  }
}
class MyWidget extends StatelessWidget {
  MyWidget({super.key});
  final controller1 = Get.put(Controller1());
  final controller2 = Get.put(Controller2());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Obx(() => (
        Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              GestureDetector(
                onTap: () => controller1.addCounter(),
                child: const Text(
                    //controller1.counter.toString(),
                    "Controller-1"),
              ),
              const Divider(),
              GestureDetector(
                onTap: () => controller2.addCounter(),
                child: const Text(
                    //controller1.counter.toString(),
                    "Controller-2"),
              ),
              const Divider(),
              Text(
                "Controller-1 = ${controller1.counter.value}",
              ),
              Text(
                "Controller-2 = ${controller2.counter.value}",
              ),
              Text(
                "C1 / C2 = ${controller1.counter.value / controller2.counter.value}",
              ),
            ],
          ),
        )
      )),
    );
  }
}
A. Sang
  • 381
  • 4
  • 11
1
  1. Remember that if you use the GetBuilder(), you have to manually update the controller state after performing some actions.

  2. It is not a good idea to initialize your controllers in the build method of your function. You should put them where they only get initialized once (outside the build method)

  3. If you have more than one controller in use in a widget, you should consider using the Obx(() {return Widget}) approach.

Read more about state management with getx here

Intellect
  • 125
  • 7
  • Regarding the second point that it is not a good idea to initialize the controller inside the build method , where to do so then because i'm in the same situation since i have a stateless widget and there is no init() in there ? – Taki Oct 22 '22 at 20:14
  • You can bind it to the view of the screen using the getx Bindings or using the BindingBuilder.put() method when you are declaring the routes for that screen. – Intellect Nov 18 '22 at 19:52
  • no that's wrong , put controller out of build method will not make any improvement in case stateless widget , the build will never recalled. – abdalmonem Dec 08 '22 at 10:25