flutterdartflutter-getxmultiple-instances

Multiple Instance with GetX tag not working in flutter


Ive been working on a multiple instance project. so i tried doing this in the counter app. but only first instance is updating. below is my all code.

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  InstanceModel selected = InstanceModel.instances.first;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Center(
            child: SizedBox(
              height: 50,
              child: Row(
                children: [
                  const SizedBox(
                    width: 50,
                  ),
                  Expanded(child: Container()),
                  Expanded(
                    flex: 3,
                    child: ListView.separated(
                        itemCount: InstanceModel.instances.length,
                        scrollDirection: Axis.horizontal,
                        separatorBuilder: (c, i) => const SizedBox(
                              width: 50,
                            ),
                        itemBuilder: (context, i) {
                          final InstanceModel instance =
                              InstanceModel.instances[i];
                          final isSelected = selected == instance;
                          return SizedBox(
                            width: 80,
                            child: ElevatedButton(
                              onPressed: () {
                                selected = instance;
                                setState(() {});
                              },
                              style: ElevatedButton.styleFrom(
                                backgroundColor:
                                    isSelected ? Colors.green : Colors.black,
                              ),
                              child: Text(instance.name),
                            ),
                          );
                        }),
                  ),
                ],
              ),
            ),
          ),
          const SizedBox(
            height: 20,
          ),
          const Text(
            'You have pushed the button this many times:',
          ),
          GetBuilder<InstanceController>(
              tag: selected.name,
              builder: (_) {
                return Text(
                  '${selected.controller.count}',
                  style: Theme.of(context).textTheme.headline4,
                );
              }),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          selected.controller.increment();
        },
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

Model class

import 'package:get/get.dart';
import 'package:train/instance_controller.dart';

class InstanceModel {
  final InstanceController controller;
  final String name;

  InstanceModel({
    required this.controller,
    required this.name,
  });

  static List<InstanceModel> instances = [
    InstanceModel(
        name: "1",
        controller:
            Get.put<InstanceController>(InstanceController(), tag: "1")),
    InstanceModel(
        name: "2",
        controller:
            Get.put<InstanceController>(InstanceController(), tag: "2")),
  ];
}

and controller class

import 'package:get/get.dart';

class InstanceController extends GetxController {
  var count = 0.obs;

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

only calling setstate is updating the second instance. i dont understand where im wrong. any help will be appreciated---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Solution

  • I really was confused at first that this might be some bug since logically your code is right, then I noticed that this about Flutter widgets replacing each by other on new state rather than completely removing that widget then adding it again in the widget tree.

    on update state ( setState(() {}) ), flutter searches first for widgets with the same type to replace each with other, in this situation, when you're expecting that GetBuilder should trigger state for each separated unique controllers, flutter just update one with the other with saving it's state.

    And to fix it, you should simply add a Key to the GetBuilder to tell flutter that each of it is unique like this:

      GetBuilder<InstanceController>(
              key: UniqueKey(), // add this
              tag: selected.name,
              builder: (_) {
                return Text(
                  '${selected.controller.count}',
                  style: Theme.of(context).textTheme.headline4,
                );
              }),